React/Router
原文地址:https://segmentfault.com/a/1190000002801128 概览在阐明React Router可以帮你解决的问题之前我们来举一个没有引用React Router 的简单例子。 没使用 React Router var About = React.createClass({ render: function () { return <h2>About</h2>; } }); var Inbox = React.createClass({ render: h2>Inbox</var Home = React.createClass({ render: h2>Home</var App = React.createClass({ render () { var Child; switch (this.props.route) { case 'about': Child = About; break; 'inbox': Child = Inbox; 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}> <path="about" {About}/> <"inbox" {Inbox}/> </Route> );
我们删除掉一些在组件内判断路由逻辑的代码。然后用 var RouteHandler = Router.RouteHandler; RouteHandler/> </div> ) } });
最后我们需要监听url的变化来动态渲染应用,加入下面的代码。 Router.run(routes,Router.HashLocation,(Root) => { React.render(<Root/>,document.body); });
接下来我们为应用添加更多的UI组件 var Message = React.createClass({ render () { h3>Message</h3>; } }); {Inbox}> <"messages/:id" {Message}/> </Route> </ 现在我们访问
嵌套的UI和多层级的URLs是 不需要耦合的。 比如说我们有/about/company 这样的URL,我们不需要嵌套UI组件到About组件中。 "about/company" {Company}/> </ 虽然说我们的URL是有层级嵌套的,但是我们UI组件中得
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 Router.run(routes,[location,],callback) // Defaults to `Router.HashLocation` // callback is called whenever the hash changes Router.run(routes,161)">// HTML5 History // callback is called when history events happen Router.run(routes,161)">// Server rendering // callback is called once,immediately. Router.run(routes,'/some/path',callback); callback(Root,state) Root state.query 举例 基本用法 javascript 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}/>,210)">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 创建的应用顶层组件。 **举例**
React.render(<Root/>,document.body); **说明** 当前路由的实例和 ``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,152)">`` 当一个被激活路由将要跳出的时候给你提供了中断跳出的方法。``component`` 是当前的组件。你可能需要检查一下 state 的状态来决定是否需要跳出。 **关于 ``callback`` 的参数** 如果你在参数列表中添加了callback,你需要在最后的时候调用它,即使你使用的是重定向。 **举例**
var Settings = React.createClass({ willTransitionTo: function (transition,query,callback) { auth.isLoggedIn((isLoggedIn) => { transition.abort(); callback(); }); },willTransitionFrom: if (component.formHasUnsavedData()) { if (!confirm('You have unsaved information,'+ 'are you sure you want to leave this page?')) { transition.abort(); } } }
} //... }); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |