本文同步自我的博客 Reeoo's Blog,欢迎移步前往,^_^
概览
本文基于React Router v1.03 版本。
React Router 是一个为React 设计的强大的路由库。可以帮助我们快速的实现路由功能,包括URL 和React components 之间的同步映射关系。 在解释React Router 如何使用之前,我们先来看看在不使用React Router 的情况下,是怎么样的,接下来的所有例子中都将使用ES2015 语法和语言特性。
不使用React Router
import React from 'react'
import { render } from 'react-dom'
const About = React.createClass({/*...*/})
const Inbox = React.createClass({/*...*/})
const Home = React.createClass({/*...*/})
const App = React.createClass({
getInitialState() {
return {
route: window.location.hash.substr(1)
}
},componentDidMount() {
window.addEventListener('hashchange',() => {
this.setState({
route: window.location.hash.substr(1)
})
})
},render() {
let Child
switch (this.state.route) {
case '/about': Child = About; break;
case '/inbox': Child = Inbox; break;
default: Child = Home;
}
return (
<div>
<h1>App</h1>
<ul>
<li><a href="#/about">About</a></li>
<li><a href="#/inbox">Inbox</a></li>
</ul>
<Child/>
</div>
)
}
})
render(<App />,document.body)
当hash 值变化的时候,App 将会根据this.state.route 的值决定渲染哪个组件(About 、Index 、Home )到页面上。这样的做法虽然看起来很简单,但是也增加了复杂性。
想象一下,如果组件 Inbox 有一些嵌套的子组件,它们的路由规则可能是这样的:/inbox/message/12345 或者 /inbox/unread 这样的, 上面的路由匹配规则很显然就不能满足我们的需求了,我们不得不修改之前的URL解析规则,写一堆复杂的代码来判断哪种URL应该呈现哪个组件(比如:App -> About,App -> Inbox -> Messages -> Message,App -> Inbox -> Messages -> Stats )。
使用React Router
首先,引入React Router
import React from 'react'
import { render } from 'react-dom'
import { Router,Route,Link } from 'react-router'
把判断路由逻辑的那段代码删除,然后加入Link 标签
const App = React.createClass({
render() {
return (
<div>
<h1>App</h1>
{/* 把`a`标签换成`Link`标签 */}
<ul>
<li><Link to="/about">About</Link></li>
<li><Link to="/inbox">Inbox</Link></li>
</ul>
{/*
把`<Child>`替换成`this.props.children`
路由会渲染正确的组件
*/}
{this.props.children}
</div>
)
}
})
最后引入<Router> 和<Route> ,由它们帮我们搞定路由。
render((
<Router>
<Route path="/" component={App}>
<Route path="about" component={About} />
<Route path="inbox" component={Inbox} />
</Route>
</Router>
),document.body)
React Router 知道哪种URL 规则下,渲染哪个组件到页面上,不需要我们自己在做任何的判断。 例如:/about 这种URL规则,会被构建成<App><About /></App> 在React Router 内部,会把<Route> 标签层级转换成路由配置。如果你不喜欢jsx 的这种写法,也可以使用对象的形式:
const routes = {
path: '/',component: App,childRoutes: [
{ path: 'about',component: About },{ path: 'inbox',component: Inbox },]
}
render(<Router routes={routes} />,document.body)
添加更多的视图
OK,现在在inbox 路由下嵌套一个messages 子路由, 首先需要添加一个新的Message组件:
const Message = React.createClass({
render() {
return <h3>Message</h3>
}
})
然后在原有的inbox 路由下面为 Message 组件添加新的路由,这样就可以得到嵌套的组件。
const Inbox = React.createClass({
render() {
return (
<div>
<h2>Inbox</h2>
{/* 渲染子组件 */}
{this.props.children}
</div>
)
}
})
render((
<Router>
<Route path="/" component={App}>
<Route path="about" component={About} />
<Route path="inbox" component={Inbox}>
{/* 在这里加入要嵌套的视图 */}
{/* render the stats page when at `/inbox` */}
<IndexRoute component={InboxStats}/>
{/* 渲染message组件 /inbox/messages/123 */}
<Route path="messages/:id" component={Message} />
</Route>
</Route>
</Router>
),document.body)
访问inbox/messages/12345 会匹配新加的路由,App->Inbox->Message ,路由层级:
<App>
<Inbox>
<Message params={ {id: '12345'} } />
</Inbox>
</App>
访问/inbox ,路由层级:
<App>
<Inbox>
<InboxStats />
</Inbox>
</App>
获取参数
当我们访问inbox/messages/12345 的时候,我们需要获取到相应的参数,然后从服务器获取对应的数据。当视图渲染的时候,路由组件会注入一些有用的属性到组件上,特别是一些从URL动态获取的参数信息,在我们这个示例里是:id
const Message = React.createClass({
componentDidMount() {
// from the path `/inbox/messages/:id`
const id = this.props.params.id
fetchMessage(id,function (err,message) {
this.setState({ message: message })
})
},// ...
})
你也可以通过查询串来获取参数,假如我们在浏览器里面访问/foo?bar=baz 这个路由,在你的组件中可以通过this.props.location.query.bar 获取bar 的值baz 。
总结
React Router 基本用法大概就这么多,一个应用往往是各种组件各种嵌套,搞明白了React Router ,就可以很轻松的玩转路由。 (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|