React-Router学习

一. 嵌套

https://zhuanlan.zhihu.com/p/20381597?columnSlug=purerender
http://www.ruanyifeng.com/blog/2016/05/react_router.html?utm_source=tool.lu
http://www.mrfront.com/2016/12/11/react-router-tutorial-part1/
http://www.mrfront.com/2016/12/23/react-router-tutorial-part2/
http://www.mrfront.com/2016/12/30/react-router-tutorial-part3/

一. 嵌套

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

实际会加载为

<App>
  <Repos/>
</App>

二. 通配符

2.1 例子

<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

2.2 参数

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

2.3 相对路径

不以/开头,匹配相对父组件的路径开始,如果不想这样,可以使用绝对路径

带参数路由一定写在底部,否则不会触发后面的规则

<Router>
  <Route path="/:userName/:id" component={UserPage}/>
  <Route path="/about/me" component={About}/>
</Router>

2.4 URL参数

比如字符串/foo?bar=baz
可以通过this.props.location.query.bar查询

三. IndexRoute

默认加载的子组件

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

访问/时,结构

<App>
  <Home/>
</App>

四. 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>生成链接,用户点击后跳转到另一个路由,可以接收Router状态

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

activeStyle属性指定选中路由样式

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

也可使用activeClassName

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

在Router组件之外,可以使用history api,导航到路由页面

import { browserHistory } from 'react-router';
browserHistory.push('/some/path');

七. IndexLink

链接到根/,不使用Link,而要使用IndexLink
对于根路由,activeStyle和activeClassName会失效,因为/会匹配任何路由;
IndexLink会使用路径的精确匹配

<IndexLink to="/" activeClassName="active">
  Home
</IndexLink>

代码中,根路由只有精确匹配时,才具有activeClassName
另外,使用Link组件的onlyActiveOnIndex属性,也可以达到效果

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

实际上,IndexLink就是对Link组件的onlyActiveOnIndex属性的包装

八. histroy

用来监听浏览器地址栏的变化,并将URL解析成一个地址对象,供React Router匹配,history属性可以设置三个值

  • browserHistory
  • hashHistory
  • createMemoryHistory

如果设置为browserHistory,背后调用的是浏览器的History api

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

需要注意的是,browserHistory服务器需要进行配置!

九. 表单处理

Link组件有时需要处理表单跳转、点击按钮跳转,如何和React Router对接呢

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

方法一: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)
  },

方法二: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

例子使用onEnter钩子替代<Redirect>组件

<Route path="inbox" component={Inbox}>
  <Route
    path="messages/:id"
    onEnter={
      ({params}, replace) => replace(`/messages/${params.id}`)
    }
  />
</Route>

onEnter钩子做认证

const requireAuth = (nextState, replace) => {
    if (!auth.isAdmin()) {
        // Redirect to Home page if not an Admin
        replace({ pathname: '/' })
    }
}
export const AdminRoutes = () => {
  return (
     <Route path="/admin" component={Admin} onEnter={requireAuth} />
  )
}


作者:zhangsean
链接:http://www.jianshu.com/p/92820ed2cffb
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值