這篇文章是整理自己學(xué)習(xí)react-router的一些簡單用法和學(xué)習(xí)資料整理谍椅,用作自己的備忘錄同時分享弧械。
入門學(xué)習(xí)
基礎(chǔ)用法
將官方示例克隆下來粗仓,運(yùn)行命令執(zhí)行起來蜕乡。
首先添加一個路由:打開入口js文件index.js
:
// render(<App/>, document.getElementById('app'))
render(<Router/>, document.getElementById('app'))
Router
是一個組件奸绷,也就是react-router
,改寫代碼:
render(
<Router history={hashHistory}>
<Route path="/" component={App}/>
</Router>
,document.getElementById('app'))
現(xiàn)在我們看到和啟動前一樣的頁面层玲,我們可以試著多加幾個路由号醉。
新添加兩個組件
modules/About.js
modules/Repos.js
// modules/About.js
import React from 'react'
export default React.createClass({
render() {
return <div>About</div>
}
})
新添加兩個路由
render(
<Router history={hashHistory}>
<Route path="/" component={App}/>
<Route path="/repos" component={Repos}/>
<Route path="/about" component={About}/>
</Router>
,document.getElementById('app'))
Route
組件定義了URL路徑與組件的對應(yīng)關(guān)系。
上面代碼中辛块,用戶訪問/repos(比如http://localhost:8080/#/repos)時畔派,加載Repos組件;訪問/about(http://localhost:8080/#/about)時憨降,加載About組件父虑。
Link
Link組件用于取代<a>元素,生成一個鏈接授药,允許用戶點(diǎn)擊后跳轉(zhuǎn)到另一個路由士嚎。
編輯modules/App.js
:
import { Link } from 'react-router'
export default React.createClass({
render() {
return <div>
<ul role="nav">
<li><Link to="/about">About</Link></li>
<li><Link to="/repos">Repos</Link></li>
</ul>
</div>
}
})
嵌套路由
之前在app上我們添加了兩個鏈接,相當(dāng)于導(dǎo)航的功能悔叽,但是導(dǎo)航應(yīng)該在每個頁面都應(yīng)該有莱衩。我們的應(yīng)用就像盒子,一個裝一個娇澎,我們的鏈接也是一層一層往下的笨蚁,假如給定url:/repos/123
,我們的組件可能就像這樣:
<App> {/* / */}
<Repos> {/* /repos */}
<Repo/> {/* /repos/123 */}
</Repos>
</App>
react的鏈接和我們的組件(UI)是一致的,鏈接和UI組件的加載是一個層級關(guān)系括细,3級鏈接就會依次加載三個路由的組件伪很。
下面我們來實(shí)現(xiàn)公共導(dǎo)航:
首先我們書寫嵌套路由:
render(
<Router history={hashHistory}>
<Route path="/" component={App}>
{/* make them children of `App` */}
<Route path="/repos" component={Repos}/>
<Route path="/about" component={About}/>
</Route>
</Router>
,document.getElementById('app'))
組件的嵌套關(guān)系,就像父子關(guān)系奋单,有孩子就有父锉试,嵌套內(nèi)的路由是外面一層的children
,我們需要把這個子組件放在父組件對應(yīng)的位置:
// modules/App.js
// ...
render() {
return (
<div>
<h1>React Router Tutorial</h1>
<ul role="nav">
<li><Link to="/about">About</Link></li>
<li><Link to="/repos">Repos</Link></li>
</ul>
{/* add this */}
{this.props.children}
</div>
)
}
// ...
現(xiàn)在看頁面览濒,就是鏈接切換時一直在頂部呆盖。只是替換了不同的子組件,像這樣:
// at /about
<App>
<About/>
</App>
// at /repos
<App>
<Repos/>
</App>
有了導(dǎo)航贷笛,我想給對應(yīng)導(dǎo)航添加當(dāng)前的樣式呢应又,react-router提供了activeStyle
和activeClassName
,直接添加內(nèi)聯(lián)樣式和添加類名來定義鏈接當(dāng)前樣式乏苦。
每次寫當(dāng)前樣式都需要加一個active株扛,有點(diǎn)麻煩,也不一定我們都記得邑贴,我們可以在Link上在封裝一層席里,作為導(dǎo)航鏈接。
// modules/NavLink.js
import React from 'react'
import { Link } from 'react-router'
export default React.createClass({
render() {
return <Link {...this.props} activeClassName="active"/>
}
})
現(xiàn)在我們就可以這樣使用:
// modules/App.js
import NavLink from './NavLink'
// ...
<li><NavLink to="/about">About</NavLink></li>
<li><NavLink to="/repos">Repos</NavLink></li>
路由參數(shù)
路由路勁:paramName
后的url會被作為參數(shù)拢驾,值可以在組件中解析this.props.params[name]
奖磁,我們試試在示例中添加參數(shù)來理解一下:
render(
<Router history={hashHistory}>
<Route path="/" component={App}>
<Route path="/repos" component={Repos}/>
<Route path="/about" component={About}/>
<Route path="/repo/:userName/:repoName" component={Repo}/>
</Route>
</Router>
,document.getElementById('app'))
然后新建一個組件:
import React from 'react'
export default React.createClass({
render() {
return (
<div>
<p>第一個鏈接參數(shù){this.props.params.userName}</p>
<p>第二個鏈接參數(shù){this.props.params.repoName}</p>
</div>
)
}
})
然后在鏈接上加一個鏈接試試:
<li><NavLink to="/repo/zhang/123">帶參數(shù)的鏈接</NavLink></li>
路由中的參數(shù)名稱會成為對應(yīng)組件的屬性名稱。
IndexRoute
我們可以通過IndexRoute
設(shè)置一個默認(rèn)加載的組件繁疤。
比如我們需要給應(yīng)用添加一個首頁咖为,我們添加一個默認(rèn)加載的組件:
import React from 'react'
export default React.createClass({
render() {
return <div>Home</div>
}
})
然后運(yùn)用IndexRoute
添加默認(rèn)加載的組件:
render(
<Router history={hashHistory}>
<Route path="/" component={App}>
<IndexRoute component={Home}/>
<Route path="/repos" component={Repos}/>
<Route path="/about" component={About}/>
<Route path="/repo/:userName/:repoName" component={Repo}/>
</Route>
</Router>
,document.getElementById('app'))
現(xiàn)在在http://localhost:8080/不僅會加載App
組件,也會加載Home
組件稠腊。
IndexLink
看看我們的例子躁染,現(xiàn)在我們沒有連接可以回到首頁,我們試著添加一個連接到首頁:
<li><NavLink to="/">Home</NavLink></li>
然而這個Home連接一直在當(dāng)前狀態(tài)架忌,也就是一直是紅色狀態(tài)吞彤。因?yàn)?code>/是所有根路徑,所有的路徑都會匹配它叹放,所以他一直是紅色狀態(tài)饰恕。react-router提供了IndexLink
來解決這個問題,用這個試試:
<li><IndexLink to="/" activeStyle={{ color: 'red' }}>Home</IndexLink></li>
history
高級用法
動態(tài)路由
對于大型應(yīng)用來說井仰,一個首當(dāng)其沖的問題就是所需加載的 JavaScript 的大小埋嵌。程序應(yīng)當(dāng)只加載當(dāng)前渲染頁所需的 JavaScript以及組件。
Route
可以定義getChildRoute
俱恶、getIndexRoute
雹嗦、getComponents
這幾個函數(shù)范舀。他們都是異步執(zhí)行的,并且只在需要時才被調(diào)用了罪。React Router 會逐漸的匹配 URL 并只加載該 URL 對應(yīng)頁面所需的路徑配置和組件锭环。
const CourseRoute = {
path: 'course/:courseId',
getChildRoutes(location, callback) {
require.ensure([], function (require) {
callback(null, [
require('./routes/Announcements'),
require('./routes/Assignments'),
require('./routes/Grades'),
])
})
},
getIndexRoute(location, callback) {
require.ensure([], function (require) {
callback(null, require('./components/Index'))
})
},
getComponents(location, callback) {
require.ensure([], function (require) {
callback(null, require('./components/Course'))
})
}
}