React Router笔记 -- 摘自阮一峰大神博客

React-Router是React体系中的路由库,它通过管理URL,实现组件的切换和状态的变化。

基本用法

Router是一个React组件:

import { Router } from 'react-router';
render(<Router/>, document.getElementById('app'));

Router组件本身只是一个容器,真正的路由要通过Route组件定义:

import { Router, Route, hashHistory } from 'react-router';

render((
  <Router history={hashHistory}>
    <Route path="/" component={App}/>
  </Router>
), document.getElementById('app'));

上面的代码表示,如果用户访问根路由 + “/”,组件(component={App})APP就会加载到:document.getElementById('app'))

注:
上面的例子中,Router组件有一个参数history,它的值hashHistory表示,路由的切换由URL的hash变化决定,即URL的#部分发生变化。举例来说,用户访问http://www.example.com/,实际会看到的是http://www.example.com/#/

另一个稍微复杂的例子:

<Router history={hashHistory}>
  <Route path="/" component={App}/>
  <Route path="/repos" component={Repos}/>
  <Route path="/about" component={About}/>
</Router>

代码解释:
用户访问/repos,则加载Repos组件,访问/about,则加载About组件。

嵌套路由

组件Route可以嵌套。

<Router history={hashHistory}>
  <Route path="/" component={App}>
    <Route path="/repos" component={Repos}/>
    <Route path="/about" component={About}/>
  </Route>
</Router>

嵌套的组件表示,用户访问/repos时,会先加载App组件,然后在它的内部再加载Repos组件。

<App>
  <Repos/>
</App>

当Router下面的字路由比较多的时候,我们可以写成这样的形式:

let routes = <Route path="/" component={App}>
  <Route path="/repos" component={Repos}/>
  <Route path="/about" component={About}/>
</Route>;

<Router routes={routes} history={browserHistory}/>

Route的path属性

Route组件的Path指定路由的匹配规则。这个属性可以省略。

并且,path属性可以使用通配符。

规则如下:

1、paramName
    :paramName匹配URL的一个部分,直到遇到下一个/、?、#为止。这个路径参数可以通过this.props.params.paramName取出。
2、()
    ()表示URL的这个部分是可选的。
3、*
    *匹配任意字符,直到模式里面的下一个字符为止。匹配方式是非贪婪模式。
4、**
    ** 匹配任意字符,直到下一个/、?、#为止。匹配方式是贪婪模式。

例子:


<Route path="/hello/:name">
// 匹配 /hello/michael
// 匹配 /hello/ryan

<Route path="/hello(/:name)">
// 匹配 /hello
// 匹配 /hello/michael
// 匹配 /hello/ryan

<Route path="/files/*.*">
// 匹配 /files/hello.jpg
// 匹配 /files/hello.html

<Route path="/files/*">
// 匹配 /files/ 
// 匹配 /files/a
// 匹配 /files/a/b

<Route path="/**/*.jpg">
// 匹配 /files/hello.jpg
// 匹配 /files/path/to/file.jpg

path属性也可以使用相对路径,也就是不以 / 开头。这是,匹配的路径就会相对于父组件的路径。

路由匹配是从上到下执行的,一旦发现匹配,就不会继续向下查找其他的规则了。

IndexRoute组件

看这个栗子:

<Router>
  <Route path="/" component={App}>
    <Route path="accounts" component={Accounts}/>
    <Route path="statements" component={Statements}/>
  </Route>
</Router>

这个栗子存在这样一个问题:如果我们访问路径 / ,不会加载任何子组件。也就是说,App组件的this.props.children是undefined。

IndexRoute就是为了解决这个问题,显式指定 Home 是根路由的子组件,即指定默认情况下加载的子组件。

我们把上面的代码改成:

<Router>
  <Route path="/" component={App}>
    <IndexRoute component={Home}/>
    <Route path="accounts" component={Accounts}/>
    <Route path="statements" component={Statements}/>
  </Route>
</Router>

那么用户访问 / 的时候,得到的组件结构是:

<App>
  <Home/>
</App>

这种组件结构就很清晰了,App只包含下级组件的共有元素,本身的展示内容则由Home组件定义。这样有利于代码分离。

注意,IndexRoute组件没有路径参数path。

Redirect组件

Redirect组件用于路由的跳转,即用户访问一个路由,会自动跳转到另一个路由。

<Route path="inbox" component={Inbox}>
  {/* 从 /inbox/messages/:id 跳转到 /messages/:id */}
  <Redirect from="messages/:id" to="/messages/:id" />
</Route>

现在,如果用户访问/inbox/messages/5,就会自动跳转到/messages/5。

IndexRedirect组件

该组件用于访问根路由的时候,将用户重定向到某个子组件。

<Route path="/" component={App}>
  <IndexRedirect to="/welcome" />
  <Route path="welcome" component={Welcome} />
  <Route path="about" component={About} />
</Route>

上面代码中,如果用户访问根路径,将自动重定向到子组件welcome。

Link组件用于取代 a 元素,生成一个连接,允许用户点击后跳转到另一个路由,它基本上就是a元素的React版本,可以接收Router状态。

render() {
  return <div>
    <ul role="nav">
      <li><Link to="/about">About</Link></li>
      <li><Link to="/repos">Repos</Link></li>
    </ul>
  </div>
}

Link组件有一个activeStyle属性,可以定义当前用户的样式。

<Link to="/about" activeStyle={{color: 'red'}}>About</Link>
<Link to="/repos" activeStyle={{color: 'red'}}>Repos</Link>

现在,这个链接将会显式红色。

还有一种方式是定义属性activeClassName为这个路由添加class

<Link to="/about" activeClassName="active">About</Link>
<Link to="/repos" activeClassName="active">Repos</Link>

如果想要链接到根路由,需要使用IndexLink组件。

这是因为,对于根路由来说,activeStyle 和 activeClassName 会失效,或者说总是生效,因为 / 会匹配任何子路由。而IndexLink组件会使用路径的精确匹配。

另一种方式是使用Link组件的onlyActiveOnIndex属性:

<Link to="/" activeClassName="active" onlyActiveOnIndex={true}>
  Home
</Link>

history 属性

Router组件的history属性,用来监听浏览器地址栏的变化,并将URL解析成一个地址对象,供React Router匹配。

history属性可以设置三种值:

browserHistory
hashHistory
createMemoryHistory

browserHistory:路由将通过URL的hash部分切换。

browserHistory:路由将采用正常的路径。

createMemoryHistory:用于服务器渲染。

表单处理

表单和React Router的对接方法:

<form onSubmit={this.handleSubmit}>
  <input type="text" placeholder="userName"/>
  <input type="text" placeholder="repo"/>
  <button type="submit">Go</button>
</form>

方法1,使用browserHistory.push

import { browserHistory } from 'react-router'

// ...
  handleSubmit(event) {
    event.preventDefault()
    const userName = event.target.elements[0].value
    const repo = event.target.elements[1].value
    const path = `/repos/${userName}/${repo}`
    browserHistory.push(path)
  },

方法2,使用context对象

export default React.createClass({

  // ask for `router` from context
  contextTypes: {
    router: React.PropTypes.object
  },

  handleSubmit(event) {
    // ...
    this.context.router.push(path)
  },
})

路由的钩子

每个路由都有Enter和Leave钩子,用户进入或者离开该路由的时候会触发。

<Route path="about" component={About} />
<Route path="inbox" component={Inbox}>
  <Redirect from="messages/:id" to="/messages/:id" />
</Route>

上面的代码中,如果用户离开/messages/:id,进入/about时,会依次触发以下的钩子。

/messages/:id的onLeave
/inbox的onLeave
/about的onEnter

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值