转载

react-router的基本用法

概览

本文基于 React Router v1.03 版本。

React Router 是一个为 React 设计的强大的路由库。可以帮助我们快速的实现路由功能,包括 URLReact 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 的值决定渲染哪个组件( AboutIndexHome )到页面上。这样的做法虽然看起来很简单,但是也增加了复杂性。

想象一下,如果组件 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 ,就可以很轻松的玩转路由。

正文到此结束
Loading...