中文 React Router
React/Router文档已废弃,关闭更新,详情请往 这里:React Router 一个针对React而设计的路由解决方案、可以友好的帮你解决React components 到URl之间的同步映射关系。 概览在阐明React Router可以帮你解决的问题之前我们来举一个没有引用React Router 的简单例子。 没使用 React Router var About = React.createClass({ render: function () { return <h2>About</h2>; } }); var Inbox = React.createClass({ render: function () { return <h2>Inbox</h2>; } }); var Home = React.createClass({ render: function () { return <h2>Home</h2>; } }); var App = React.createClass({ render () { var Child; switch (this.props.route) { case 'about': Child = About; break; case 'inbox': Child = Inbox; break; default: Child = Home; } return ( <div> <h1>App</h1> <Child/> </div> ) } }); function render () { var route = window.location.hash.substr(1); React.render(<App route={route} />,document.body); } window.addEventListener('hashchange',render); render(); // render initially 在hash值改变的时候, 引入路由 解决复杂的URL和层级组件之间的映射关系式React Router 的核心。我们使用声明式的方式为我们举的例子引入路由。我们使用JSX的方式来进行路由的配置,这样我们可以通过属性的方式来配置页面视图的层级关系。 var Router = require('react-router'); var Route = Router.Route; // declare our routes and their hierarchy var routes = ( <Route handler={App}> <Route path="about" handler={About}/> <Route path="inbox" handler={Inbox}/> </Route> ); 我们删除掉一些在组件内判断路由逻辑的代码。然后用 var RouteHandler = Router.RouteHandler; var App = React.createClass({ render () { return ( <div> <h1>App</h1> <RouteHandler/> </div> ) } }); 最后我们需要监听url的变化来动态渲染应用,加入下面的代码。 Router.run(routes,Router.HashLocation,(Root) => { React.render(<Root/>,document.body); });
接下来我们为应用添加更多的UI组件 var Message = React.createClass({ render () { return <h3>Message</h3>; } }); var routes = ( <Route handler={App}> <Route path="about" handler={About}/> <Route path="inbox" handler={Inbox}> <Route path="messages/:id" handler={Message}/> </Route> </Route> ); 现在我们访问 获取url的参数 var Message = React.createClass({ componentDidMount: function () { // from the path `/inbox/messages/:id` var id = this.props.params.id; fetchMessage(id,function (err,message) { this.setState({ message: message }); }) },// ... }); 嵌套的UI和多层级的URLs是 不需要耦合的。 比如说我们有/about/company 这样的URL,我们不需要嵌套UI组件到About组件中。 var routes = ( <Route handler={App}> <Route path="about" handler={About}/> <Route path="about/company" handler={Company}/> </Route> ); 虽然说我们的URL是有层级嵌套的,但是我们UI组件中得 现在让我们往路由中添加url 1、url 要以 var routes = ( <Route handler={App}> <Route path="inbox" handler={Inbox}> <Route path="messages/:id" handler={Message}/> <Route path="/archive/messages/:id" handler={Message}/> </Route> </Route> ); 这就是React Router的核心,应用的UI组件是层层嵌套的。现在我们可以让这些嵌套的UI组件和URL规则保持同步了。 Route 配置DefaultRoute一个 Props 举例 <Route path="/" handler={App}> <!-- When the url is `/`,this route will be active. In other words,`Home` will be the `<RouteHandler/>` in `App`. --> <DefaultRoute handler={Home}/> <Route name="about" handler={About}/> <Route name="users" handler={Users}> <Route name="user" handler={User} path="/user/:id"/> <!-- when the url is `/users`,this will be active --> <DefaultRoute name="users-index" handler={UsersIndex}/> </Route> </Route> NotFoundRoute
提示 props
举例 <Route path="/" handler={App}> <Route name="course" path="course/:courseId" handler={Course}> <Route name="course-dashboard" path="dashboard" handler={Dashboard}/> <!-- ie: `/course/123/foo` --> <NotFoundRoute handler={CourseRouteNotFound} /> </Route> <!-- ie: `/flkjasdf` --> <NotFoundRoute handler={NotFound} /> </Route> 最后一个 Redirect
props
举例 <!-- lets say we want to change from `/profile/123` to `/about/123` and redirect `/get-in-touch` to `/contact` --> <Route handler={App}> <Route name="contact" handler={Contact}/> <Route name="about-user" path="about/:userId" handler={UserProfile}/> <Route name="course" path="course/:courseId"> <Route name="course-dashboard" path="dashboard" handler={Dashboard}/> <Route name="course-assignments" path="assignments" handler={Assignments}/> </Route> <!-- `/get-in-touch` -> `/contact` --> <Redirect from="get-in-touch" to="contact" /> <!-- `/profile/123` -> `/about/123` --> <Redirect from="profile/:userId" to="about-user" /> <!-- `/profile/me` -> `/about-user/123` --> <Redirect from="profile/me" to="about-user" params={{userId: SESSION.USER_ID}} /> </Route>
Route
Top-LevelRouter.create创建一个新的路由。 Signature Options
Method 举例 // the more common API is Router.run(routes,Router.HistoryLocation,callback); // which is just a shortcut for var router = Router.create({ routes: routes,location: Router.HistoryLocation }); router.run(callback); Router.runThe main API into react router. It runs your routes,matching them against a location,and then calls back with the next state for you to render. signature
举例 // Defaults to `Router.HashLocation` // callback is called whenever the hash changes Router.run(routes,callback); // HTML5 History // callback is called when history events happen Router.run(routes,callback); // Server rendering // callback is called once,immediately. Router.run(routes,'/some/path',callback);
举例 基本用法
var resolveHash = require('when/keys').all; var SampleHandler = React.createClass({ // this is going to be called in the `run` callback fetchData: function (params) { return fetchStuff(params); } }, Router.run(routes,function (Root,state) { // create the promises hash // gather up the handlers that have a static `fetchData` method return route.handler.fetchData; }).reduce(function (promises,route) { // reduce to a hash of `key:promise` promises[route.name] = route.handler.fetchData(state.params); return promises; },{}); resolveHash(promises).then(function (data) { // wait until we have data to render,the old screen stays up until // we render React.render(<Root data={data}/>,document.body); }); something.serve(function (req,res) { // could fetch data like in the previous example fetchData(state.matches).then(function (data) { var html = React.renderToString(<Root data={data} />); res.send(html); }); }); #Components ##Link 用于在应用程序中导航的一种主要方式。``Link``将会渲染出标签属性href 变得容易被理解。 当``Link``定位的路由被激活的时候自动 显示为 定义的 ``activeClassName`` 和/或者 ``activeStyle`` 定义的样式。 **Props** ``to`` 要被定位到的路由名字,或者是完整的路径 ``params`` 包含了名字/值的对象,和路由地址的动态段对应一致。 ``query`` 一个包含名字/值 的对象,它会成为地址中的查询参数 **举例** // given a route config like this // create a link with this // though,if your user properties match up to the dynamic segements: ``query`` 一个包装成javascript对象的字符串查询参数 ``activeClassName`` 当路由被激活是 ``Link`` 接收的 className,默认值为 ``active`` ``activeStyle `` 当路由被激活是链接元素 展示的style样式。 ``onClick`` 对点击时间的常规处理,仅仅在标签``<a>`` 上起效。调用 ``e.preventDefault`` 或者是返回false 将会阻止阻止事件发射。通过 ``e.stopPropagation()`` 将会阻止时间冒泡。 **others** 你也可以在<a>上传递 props,例如 title,id,className 等。 **举例** 提供一个形式像 ``<Router name="user" path="/user/:userid" />:`` 这样的路由 <Link to="user" params={{userId: user.id}} query={{foo: bar}}>{user.name}</Link> <!-- or if you have the full url already,you can just pass that in --> <!-- change the activeClassName --> <!-- change style when link is active --> ##Root React router 创建的应用顶层组件。 **举例** Router.run(routes,(Root) => { **说明** 当前路由的实例和 ``Root`` 一致。 var MyRouter = Router.create({ routes }); MyRouter.run((Root) => { 当前这仅仅是一个实现的细节,我们会逐步将它设计成一个公共的API。 ##Route Handler 用户定义的一个组件,作为传递给``Routes`` 的一个 ``handler`` 属性。 路由会在你通过 ``RouterHandler`` 渲染组件的时候给你注入一些属性值。同时在路由转换的时候调用一些生命周期的静态方法。 **注入的属性** ``params`` url 中的动态段。 ``query`` url中的查询参数 ``path`` 完整的url 路劲 **举例** // given a route like this: // and a url like this: var Students = React.createClass({ this.props.params.courseId; // "123" this.props.query.sort; // "name" this.props.path; // "/course/123/students?sort=name" // ... } **静态的生命周期方法** 你可以定义一些在路由转换时会调用的静态方法到你的路由handler 对应的组件中。 ``willTransitionTo(transition,params,query,callback)`` 当一个handler 将要被渲染的时候被调用。为你提供了中断或者是重定向的机会。你可以在异步调用的时候暂停转换,在完成之后可以调用``callback(error)`` 方法。或者在参数列表中省略callback。 ``willTranstionFrom(transition,component,callback)`` 当一个被激活路由将要跳出的时候给你提供了中断跳出的方法。``component`` 是当前的组件。你可能需要检查一下 state 的状态来决定是否需要跳出。 **关于 ``callback`` 的参数** 如果你在参数列表中添加了callback,你需要在最后的时候调用它,即使你使用的是重定向。 **举例** var Settings = React.createClass({ willTransitionTo: function (transition,callback) { auth.isLoggedIn((isLoggedIn) => { transition.abort(); callback(); }); },willTransitionFrom: function (transition,component) { if (component.formHasUnsavedData()) { if (!confirm('You have unsaved information,'+ 'are you sure you want to leave this page?')) { transition.abort(); } } } } //...}); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |