react router--childRouter

来源:互联网 发布:微软平板软件下载 编辑:程序博客网 时间:2024/06/08 00:16

Router

笔者解读:React Router的组件,可保持UI和URL的同步看名字的话,react-router大概跟其他语言里面路由的功能和作用是差不多的,差别应该是在用法和形式上面,也就是神一样,形不一样(容我装一下AC之间)。

这好像是一个官方文档上面的例子:

复制代码
import React from 'react'import{ render } from 'react-dom'// 首先我们需要导入一些组件...import{ Router, Route, Link } from 'react-router'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>        {/*          接着用 `this.props.children` 替换 `<Child>`          router 会帮我们找到这个 children        */}        {this.props.children}    </div>)}})// 最后,我们用一些 <Route> 来渲染 <Router>。// 这些就是路由提供的我们想要的东西。React.render((<Router>    <Route path="/" component={App}>    <Route path="about" component={About}/>    <Route path="inbox" component={Inbox}/></Route></Router>), document.body)
复制代码

 react-router会为我们搭建嵌套UIeg: 当路径是/about时,react-router会搭建出

 <App> <About /> </App>

这样的东东。

在Inbox内部嵌套Message,是的还是一个贴过来的例子:

 

复制代码
// 新建一个组件让其在 Inbox 内部渲染const Message = React.createClass({  render() {    return <h3>Message</h3>  }})const Inbox = React.createClass({  render() {    return (      <div>        <h2>Inbox</h2>        {/* 渲染这个 child 路由组件 */}        {this.props.children || "Welcome to your Inbox"}      </div>    )  }})React.render((  <Router>    <Route path="/" component={App}>      <Route path="about" component={About} />      <Route path="inbox" component={Inbox}>        {/* 添加一个路由,嵌套进我们想要嵌套的 UI 里 */}        <Route path="messages/:id" component={Message} />      </Route>    </Route>  </Router>), document.body)
复制代码

Router与Route一样都是react的组件Route的path属性表示路由组件对应的路径,可以是绝对路径也可以是相对路径在Route中可以用component指定单个组件,或者通过components指定多个组件集合param通过/:param的方式传递(path="messages/:id"),这种写法与express以及ruby on rails一致,符合RestFul规范。

 

获取URL参数

复制代码
const Message = React.createClass({    componentDidMount(){        // 来自于路径 `/inbox/messages/:id`        const id =this.props.params.id        fetchMessage(id,function(err, message){            this.setState({ message: message })        }    )},    // ...})
复制代码

还可以用 query 字符串来访问参数。比如要访问 /foo?bar=baz,

你可以通过访问this.props.location.query.bar 从 Route 组件中获得 "baz" 。

路由配置

其实就是告诉router怎样匹配URL以及匹配完之后怎样去执行代码例:添加一个默认的首页URL为/时,

想渲染一个App中的组件,但是这个时候App中render中的子组件也就是this.props.children还是undefined,

这个时候我们就需要用IndexRoute设置默认的页面

<IndexRoute component={Dashboard} />

如果在路径中使用绝对路径就可以做到像这样,/inbox/messages/:id 变成 /messages/:id但是细心的盆宇会发现,

其实这样做是改变了URL,做出如此不符合规范的行为,就会造成这样的现象,

如果有人访问/inbox/messages/5时就会找不到页面,那么如何补救呢,

这时候Redirect就出现了Redirect是一个重定向组件,有from和to两个属性我们可以用Redirect重新定向这个URL。

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

进入和离开的HookRoute可以定义onEnter和onLeave两个hook,

hook会在页面跳转确认时触发一次:权限验证或在路由跳转之前将一些数据持久化保存起来在路由跳转过程中,

onLeave hook 会在所有将离开的路由中触发,从最下层的子路由开始直到最外层父路由结束。

然后onEnter hook会从最外层的父路由开始直到最下层子路由结束。

一个比较通俗易懂的例子,点击链接,从/messages/5跳转到/about,hook的执行就是下面这个样子:

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

除了上面这种组件一样的方法之外,路由的配置书写方法还可以这样子,

复制代码
const routeConfig =[{ path:'/',  component: App,  indexRoute:{ component: Dashboard },  childRoutes:[    { path:'about',       component: About },    { path:'inbox',      component: Inbox,      childRoutes:[{        path:'/messages/:id',        component: Message    },    { path:'messages/:id',      onEnter:function(nextState, replaceState){      replaceState(null,'/messages/'+ nextState.params.id)}    }]  }]}]React.render(<Router routes={routeConfig}/>, document.body)
复制代码

很像写配置文件一样的。

路由匹配原理

路由有三个属性来决定它是否与一个“URL”相匹配

嵌套关系 路径语法 优先级

嵌套关系

官方解释是酱紫的:React-Router 使用路由嵌套的概念来让你定义 view 的嵌套集合,当一个给定的 URL 被调用时,整个集合中(命中的部分)都会被渲染。嵌套路由被描述成一种树形结构。React Router 会深度优先遍历整个路由配置来寻找一个与给定的 URL 相匹配的路由。 就是说,react-router的路由是使用一种组件相互嵌套的方式定义的,这个跟react-redux里面组件的结构也很一致

路径语法:

路由路径是匹配一个(或一部分)URL的一个字符串模式。

:paramName 匹配一段位于/,?或# 之后的URL。

命中的部分将被作为一个参数() 在它内部的内容被认为是可选的 * 匹配任意字符(非贪婪的)直到命中下一个自负或者整个URL的末尾,并创建一个splat参数

 

<Route path="/hello/:name">// 匹配 /hello/michael 和 /hello/ryan<Route path="/hello(/:name)">// 匹配 /hello, /hello/michael 和 /hello/ryan<Route path="/files/*.*">// 匹配 /files/hello.jpg 和 /files/path/to/hello.jpg

优先级

路由算法会根据定义的顺序自顶向下匹配路由,

因此,当你拥有两个兄弟路由节点配置时,你必须确认前一个路由不会匹配后一个路由中的路径。

例如,千万不要这么做:

<Route path="/comments".../><Redirect from="/comments".../>

这样的话,前面配好的路由就会被重定向。

 

原创粉丝点击