reactJS之react-route
1. 使用react-router
用巢狀的<Router/>來定義檢視的層級,當Route啟用時提供React的元素來處理這些Route
React Router會根據URL來匹配最深層級的Route, 然後啟用巢狀在UI裡面的該Route的整個分支
你只需簡單使用<RouteHandle/>元件來渲染啟用的子Router
var App = React.createClass({ render: function () { return ( <div> <header> <ul><li><Link to="app">Dashboard</Link></li> <li><Link to="inbox">Inbox</Link></li> <li><Link to="calendar">Calendar</Link></li> </ul> Logged in as Jane </header> {/* this is the important part */} <RouteHandler/> </div> ); } });
var routes = ( <Route name="app" path="/" handler={App}> <Route name="inbox" handler={Inbox}/> <Route name="calendar" handler={Calendar}/> <DefaultRoute handler={Dashboard}/> </Route> ); Router.run(routes, function(都不帶任何引數)(Handler) { React.render(<Handler/>, document.body); });
當我們登入/inbox時,名字為inbox的route會匹配上,而且他的父route app也會匹配. run方法會回撥接收者Handler, 因此所有匹配上的資訊都會被執行.
渲染Handler確實僅僅渲染App,因為它是最高的匹配上的route handler. 因為 inbox 是啟用的child route, 在 App 中渲染<RouteHandler/>時會渲染 Inbox 元素, <RouteHandler /> 和 Ember中的{{outlet}}或Angular中的<div ng-view/>相同.
注意到我們不需要 <Header/> 元素,因為我們沒必要重複它. React Router會為我們共享UI
2. 更多巢狀
巢狀深層UI也不是問題,比如 Inbox 頁面, 它的左邊是個訊息管理列表, 右邊是訊息詳細內容,上面是工具條. 工具條和訊息列表是固定的,訊息內容隨著對列表的點選變化.
React Router handle是這樣的:
var Inbox = React.createClass({ render: function () { return ( <div> <Toolbar/> <Messages/> <RouteHandler/> </div> ); } }); var routes = ( <Route handler={App}> <Route name="inbox" handler={Inbox}> <Route name="message" path=":messageId" handler={Message}/> <DefaultRoute handler={InboxStats}/> </Route> <Route name="calendar" handler={Calendar}/> <DefaultRoute handler={Dashboard}/> </Route> );Inbox 現在在它的渲染方法裡有了一個<RouterHandler/>, 就像它的父元素
我們現在增加了子route在inbox裡, 訊息和狀態的頁面可以在裡面渲染
3. 動態部分
我們增加訊息介面時,引入了'動態部分'到URL裡.這部分從url中解析,並在 run 的回撥裡獲取, 或者從 this.context.router router處理器中. 下面展示一下如何訪問到引數
Remember our message route looks like this:
<Route name="message" path=":messageId" handler={Message}/>
Lets look at accessing the messageId
in Message
.
var Message = React.createClass({ contextTypes: { router: React.PropTypes.func }, render: function () { return ( <div>{this.context.router.getCurrentParams().messageId}</div> ); } });
Assuming the user navigates to /inbox/123
, this.context.router.getCurrentParams().messageId
is
going to be '123'
.
Alternatively, you can pass the param data down through the view hierarchy from the run
callback and access the
params with this.props.params
.
Router.run(routes, function (Handler, state) { var params = state.params; React.render(<Handler params={params}/>, document.body); }); (state.params是獲取的url引數??) // and then pass the params down to every use of `<RouteHandler/>`<RouteHandler {...this.props}/>// Inbox ends up looking like thisvar Inbox = React.createClass({ render: function () { return ( <div><Toolbar/><Messages/><RouteHandler {...this.props}/> // 這裡傳遞下去</div> ); } }); // and Message changes to:var Message = React.createClass({ render: function () { return ( <div>{this.props.params.messageId}</div> // 這裡使用 ); } });
4. 關於動態部分的重點
detail切換的時候,以下方法不會被執行:getInitialState
,componentWillMount
, componentWillUnmount
or componentDidMount
如果想要強制re-mount,可以賦一個唯一的key值