参考资料
github官网给出的tutorial;
tutorial
rendering-a-route
hashHistory
You should get the same screen as before,but this time with some junk in the URL. We're using
hashHistory
--it manages the routing history with the hash portion of the url. It's got that extra junk to shim some behavior the browser has natively when using real urls. We'll change this to use real urls later and lose the junk,but for now,this works great because it doesn'trequire any server-side configuration.
说明:hashHistory
管理的是url的hash部分,通过hash值匹配url
navigating-with-link
Link
Perhaps the most used component in your app is
Link
.
说明:Link
. 也是一个组件,通过他方便我们找到路由其他部分
import { Link } from 'react-router' <li><Link to="/about">About</Link></li>
nested-routes
Nested UI and Nested URLs
Have you ever noticed your app is just a series of Boxes inside Boxes inside Boxes? Have you also noticed your URLs tend to be coupled to that nesting? For example given this url,
/repos/123
,our components would probably look like this:<App> {/* / */} <Repos> {/* /repos */} <Repo/> {/* /repos/123 */} </Repos> </App>And our UI something like:
+-------------------------------------+ | Home Repos About | <- App +------+------------------------------+ | | | Repos -> | repo | Repo 1 | | | | | repo | Boxes inside Boxes | | | inside Boxes ... | <- Repo | repo | | | | | | repo | | | | | +------+------------------------------+React Router embraces this by letting you nest your routes,which automatically becomes nested UI.
说明:嵌套ui(路由,router可以理解为一个组件)
<Route path="/" component={App}> {/* make them children of `App` */} <Route path="/repos" component={Repos}/> <Route path="/about" component={About}/> </Route>
Next,render children inside ofApp
.
// modules/App.js // ... render() { return ( <div> <h1>React Router Tutorial</h1> <ul role="nav"> <li><Link to="/about">About</Link></li> <li><Link to="/repos">Repos</Link></li> </ul> {/* add this */} {this.props.children} </div> ) } // ...
Alright,now go click the links and notice that theApp
component continues to render while the child route's component gets swapped around asthis.props.children
:)
说明:嵌套组件配置之后,App就可以管理子组件Repos,About了。
{this.props.children}显示的就是url对应的子组件的内容。
index.js只是配置路由关系而已,不处理应用的呈现关系。呈现关系是由url决定的。
比如http://localhost:8080/,应用找的是app这个组件,然后根据这个组件的route,呈现自己的层级关系。
The best way to build large things is to stitch small things together.大而化小,化繁为简。
What happens if you move theAbout
route outside ofApp
?,如果将about放回原处。
Active Links
Active Styles
<li><Link to="/about" activeStyle={{ color: 'red' }}>About</Link></li>
说明:多个样式,使用json格式
<li><Link to="/about" activeStyle={{color:'red',fontSize:'30px'}}>About</Link></li>
注意font-size变成驼峰。或者使用
<li><Link to="/about" activeStyle={{"color":'red',"font-size":'30px'}}>About</Link></li>
双引号key格式
Active Class Name
<li><Link to="/about" activeClassName="active">About</Link></li>
Nav Link Wrappers
navLink封装。
NavLink.js
// modules/NavLink.js import React from 'react' import { Link } from 'react-router' export default React.createClass({ render() { return <Link {...this.props} activeClassName="active"/> } })
Now you can go change your links toNavLink
s.
// modules/App.js import NavLink from './NavLink' // ... <li><NavLink to="/about">About</NavLink></li> <li><NavLink to="/repos">Repos</NavLink></li>
Params
URL Params
These URLs would match a route path like this:
/repos/:userName/:repoName
说明:The parts that start with:
are URL parameters whose values will be parsed out and made available to route components onthis.props.params[name]
.
通过this.props.params[name]
.取得参数。例如应用中配置的<Route path="/repos/:userName/:repoName" component={Repo}/>那么可以根据{this.props.params.repoName}
找到对应的repoName,例如
http://localhost:8080/#/repos/reactjs/react-router,得到的结果就是react-router,如果{this.props.params.userName}
得到的就是reactjs了。
More Nesting
nest theRepo
route under theRepos
route. Then go renderthis.props.children
inRepos
.
// index.js // ... <Route path="/repos" component={Repos}> <Route path="/repos/:userName/:repoName" component={Repo}/> </Route>
// Repos.js // ... <div> <h2>Repos</h2> <ul> <li><Link to="/repos/reactjs/react-router">React Router</Link></li> <li><Link to="/repos/facebook/react">React</Link></li> </ul> {/* will render `Repo.js` when at /repos/:userName/:repoName */} {this.props.children} </div>
说明:定义route层级关系之后,利用this.props.children
显示子组件内容.如上定义了repos>repo之后,在父组件repos里面,利用this.props.children
就可以显示(预览)子组件的内容了。
Active Links
Notice how both the/repos
link up top and the individual repo links are both active? When child routes are active,so are the parents.
说明:子组件active之后,父组件如果设置了active,也相应的会被active了。
Index Routes
When we visit/
in this app it's just our navigation and a blank page.
if we have any children inApp
,and if not,renderHome
:
说明:根目录/
指定。
// modules/App.js import Home from './Home' // ... <div> {/* ... */} {this.props.children || <Home/>} </div> //...
如果url有渲染子组件,那么就显示子组件内容。如果没有就显示home组件。如
url:http://localhost:8080/#/?_k=sn17mk 为根目录,后面没有带hash,那么显示的内容为
另一种处理方式,就是代码和结构分离,利用配置的方式去指定。
indexRoute
<Route path="/" component={App}> {/* add it here,as a child of `/` */} <IndexRoute component={Home}/> <Route path="/about" component={About}/> </Route>
Index Links
如果使用普通的自定义navlink的方式。
<li><NavLink to="/">Home</NavLink></li>
这种方式,当url为/xx的时候。/根目录也会被active,使用下面的两种方式就可以避免了。
IndexLink
// App.js import { IndexLink } from 'react-router' // ... <li><IndexLink to="/" activeClassName="active">Home</IndexLink></li>
使用这个IndexLink标签而不是使用自定义的NavLink标签是为了防止activeClass 找父route的时候对/根目录都active了。
onlyActiveOnIndex
这种方式也可以达到上面效果。
<li><Link to="/" activeClassName="active" onlyActiveOnIndex={true}>Home</Link></li>
这两种方式都可以
clean-urls
The URLs in our app right now are built on a hack: the hash. It's the default because it will always work,but there's a better way.
Modern browsers let JavaScript manipulate the URL without making an http request,so we don't need to rely on the hash (
#
) portion of the url to do routing,but there's a catch (we'll get to it later).
可以不以来hash来制定url,现代浏览器可以制定url,不需要请求http服务。
Configuring Browser History
browserHistory
Open upindex.js
and importbrowserHistory
instead ofhashHistory
.
// index.js // ... // bring in `browserHistory` instead of `hashHistory` import { Router,Route,browserHistory,IndexRoute } from 'react-router' render(( <Router history={browserHistory}> {/* ... */} </Router> ),document.getElementById('app'))
利用browserHistory
instead ofhashHistory
.来指定页面跳转
使用browserHistory之后链接地址就不需要hash值了,为常见的链接了。客户端js可以改变url显示,不需要向服务器发送请求。
但是如果刷新会出现
因为这个链接是客户端链接,可以理解为是一个假连接,或者是hash的一种变换。
Configuring Your Server
Your server needs to deliver your app no matter what URL comes in,because your app,in the browser,is manipulating the URL. Our current server doesn't know how to handle the URL.
The Webpack Dev Server has an option to enable this. Open uppackage.json
and add--history-api-fallback
.
"start": "webpack-dev-server --inline --content-base . --history-api-fallback"
We also need to change our relative paths to absolute paths inindex.html
since the URLs will be at deep paths and the app,if it starts at a deep path,won't be able to find the files.
<!-- index.html --> <!-- index.css -> /index.css --> <link rel="stylesheet" href="/index.css"> <!-- bundle.js -> /bundle.js --> <script src="/bundle.js"></script>
Stop your server if it's running,thennpm start
again. Look at those clean URLs :)
需要配置package.json,让服务器知道如何处理请求,另外也要修改index.html里面的index.css,bundle.js路径,需要将相对路径--》绝对路径
刷新可以,深层次链接的话,比如点repos的子连接,刷新也可以了。★★★★★html里面的js,css一定要改相对路径为绝对路径。
productionish-server
None of this has anything to do with React Router
react router与服务器无关。为了更接近实际,
配置生产环境。
注意看文档是怎么配置的。
注意,这里配置运行环境的时候window要使用cmd命令窗口,不能使用powershell,或者使用类unix的bash环境(比如git bash),就可以直接使用命令了。
NODE_ENV=production npm start # For Windows users: # SET "NODE_ENV=production" && npm start
按照示例代码,把index.html和index.css都要挪到public文件夹(正式环境发布文件夹,压缩后的代码都会放在这里。)
navigating
Navigating Programatically
While most navigation happens with
Link
,you can programmatically navigate around an application in response to form submissions,button clicks,etc.
链接操作。再提交表单,或者点击事件的时候页面url的变迁有两种方式
1.使用 browserHistory
browserHistory.push(path)
这种方式有个弊端就是链接必须是history认识的,不然没有办法作用。比如在demo中输入了userName:2,pwd:3;url:http://localhost:8080/repos/2/3 url就没有作用了。页面跳转,history找不到这个url。显示为空了。
2.
You can also use therouter
thatRouter
provides on "context". First,you ask for context in the component,and then you can use it:
export default React.createClass({ // ask for `router` from context contextTypes: { router: React.PropTypes.object },// ... handleSubmit(event) { // ... this.context.router.push(path) },// .. })
使用router提供的context上下文对象。使用这种方式,即使上面的url也可以正常显示。
server-rendering
server渲染主要通过服务端利用模板,渲染给客户端。注意数据同步的问题。
相关配置,直接参考doc文档。
doc
要点参考
RouteConfiguration
Decoupling the UI from the URL
分离ui和url配置。
<Router> <Route path="/" component={App}> {/* Show the dashboard at / */} <IndexRoute component={Dashboard} /> <Route path="about" component={About} /> <Route path="inBox" component={InBox}> <Route path="messages/:id" component={Message} /> </Route> </Route> </Router>
上面的配置inBox下面再配置message组件,ui和url融合在一起。
如果要分离的话使用下面的方式,这样类似分模块,可以一层一层细分route
<Router> <Route path="/" component={App}> <IndexRoute component={Dashboard} /> <Route path="about" component={About} /> <Route path="inBox" component={InBox} /> {/* Use /messages/:id instead of /inBox/messages/:id */} <Route component={InBox}> <Route path="messages/:id" component={Message} /> </Route> </Route> </Router>
这种方式访问的话,就不能使用/inBox/messages/:id 访问方式了,而是要使用/messages/123456,这样的方式去访问了。要解决这个问题,需要用到下面的Preserving urls
Preserving URLs
redirect
Wait a minute ... we just changed a URL!That's not cool. Now everyone who had a link to/inBox/messages/5
has abroken link. :(
Not to worry. We can use a<Redirect>
to make sure that URL still works!
前面ui和url分离了。导致url需要变化,如果我们不想改变url访问路径,这里使用redirect来处理。
<Router> <Route path="/" component={App}> <IndexRoute component={Dashboard} /> <Route path="about" component={About} /> <Route path="inBox" component={InBox}> {/* Redirect /inBox/messages/:id to /messages/:id */} <Redirect from="messages/:id" to="/messages/:id" /> </Route> <Route component={InBox}> <Route path="messages/:id" component={Message} /> </Route> </Route> </Router>
Now when someone clicks on that link to/inBox/messages/5
they'll automatically be redirected to/messages/5
. 原文链接:https://www.f2er.com/react/305892.html