官網(wǎng)地址
https://reactrouter.com/web/guides/quick-start
React Router 的組成部分
react-router : 是瀏覽器與原生應(yīng)用的公共部分颤陶。
react-router-dom:是用于瀏覽器的狼讨。
react-router-native: 是用于原生應(yīng)用的尸疆。
react-router
是核心部分招盲。react-router-dom
提供了瀏覽器使用需要的定制組件。react-router-native
則專門提供了在原生移動應(yīng)用中需要用到的部分慧起。所以疹吃,如果在本例中實現(xiàn)瀏覽器開發(fā)就只需要安裝react-router-dom
。
安裝react-router-dom
執(zhí)行以下命令
npm install react-router-dom --save
react-router
Browser Router : 這是對
Router
接口的實現(xiàn)乓搬。使得頁面和瀏覽器的history保持一致思犁。如:window.location
。Hash Router : 和上面的一樣进肯,只是使用的是 URL 的hash部分激蹲,比如:
window.location.hash
。Native Router: 處理react native內(nèi)的路由江掩。
Static Router: 處理靜態(tài)路由学辱。
<BrowserRouter>
和<HashRouter>
是可以在瀏覽器中使用的。如果你使用的是一個非靜態(tài)的站點环形、要處理各種不同的URL那么你就需要使用BrowserRouter
策泣。相反的如果你的server只處理靜態(tài)的URL,那么就使用HashRouter
抬吟。**
route
Route
組件可以使用如下的屬性:
path屬性萨咕,字符串類型,它的值就是用來匹配url的火本。
component屬性危队,它的值是一個組件。在
path
匹配成功之后會繪制這個組件钙畔。exact屬性茫陆,這個屬性用來指明這個路由是不是排他的匹配。
strict屬性擎析, 這個屬性指明路徑只匹配以斜線結(jié)尾的路徑簿盅。
還有其他的一些屬性,可以用來代替component
屬性叔锐。
render屬性挪鹏,一個返回React組件的方法。傳說中的rencer-prop就是從這里來的愉烙。
children屬性,返回一個React組件的方法解取。只不過這個總是會繪制步责,即使沒有匹配的路徑的時候。
多數(shù)的時候是用component
屬性就可以滿足。但是蔓肯,某些情況下你不得不使用render
或children
屬性遂鹊。
- match
- location
- history
如:
使用組件:
<Route exact path="/" component={HomePage} />
使用`render`屬性實現(xiàn)內(nèi)聯(lián)繪制:
<Route path="/" render={()=><div>HomePage</div>} />
const FadingRoute = ({ component, ...rest }) => (
<Route {...rest} render={(props) => (
<FadeIn>
<componnet {...props} />
</FadeIn>
)} />
)
<FadingRoute path="/cool" component={Something} />
使用`children`:
<ul>
<ListItemLink to="/somewhere" />
<LinkItemLink to="/somewhere-else" />
</ul>
const ListItemLink = ({to, ...rest}) => (
<Route path={to} children={({math}) => (
<li className={match ? 'active' : ''}>
<Link to={to} {...rest} />
</li>
)} />
)
URL / Path / Route 的參數(shù)
通常情況下,我們都會在路徑里添加參數(shù)蔗包。這樣方便在不同的組件之間傳遞一些必要的數(shù)據(jù)秉扑。那么我們?nèi)绾尾拍塬@取到這些傳遞的參數(shù),并傳遞給組件中呢调限?我們只需要在路徑的最后加上/:param
。如:
<Route path="/:param1" component={HomePage} />
const HomePage = ({match}) => (
<div>
<h1> parameter => {match.params.param1} </h1>
</div>
);
一旦有路徑可以匹配成功耻矮,那么就會穿件一個擁有如下屬性的對象秦躯,并傳入繪制的組件里:
- url: 匹配的url。
- path:就是path裆装。
- isExact:如果
path
和當(dāng)前的widnow.location
的path部分完全相同的話踱承。 - params:在URL里包含的參數(shù)。
Link
Link
是react router v4特有的一個組件哨免。是用來代替上一版的anchor link茎活。使用Link
可以在React應(yīng)用的不同頁面之間跳轉(zhuǎn)。與unclor會重新加載整個頁面不同琢唾,Link
只會重新加載頁面里和當(dāng)前URL可以匹配的部分
Link
組件需要用到to
屬性妙色,這個屬性的值就是react router要跳轉(zhuǎn)到的地址。如:
import { Link } from 'react-router-dom';
const Nav = () => (
<Link to '/'>Home</Link>
);
to
屬性的值可以是一個字符串慧耍,也可以是一個location(pathname, hash, state和search)對象身辨。比如:
<Link to{{
pathname: '/me',
search: '?sort=asc',
hash: '#hash',
state: { fromHome: true }
}} />
< Link > 和< NavLink >
NavLink
是Link
的一個子類,在Link組件的基礎(chǔ)上增加了繪制組件的樣式芍碧,比如:
<NavLink to="/me" activeStyle={{SomeStyle}} activeClassName="selected">
My Profile
</NavLink>
使用react-router-dom實現(xiàn)第一個demo
首先煌珊,引入必要的組件。比如:Route
和BrowserRouter
泌豆。
import { BrowserRouter, Route } from 'react-router-dom';
創(chuàng)建一些組件和一些Html標(biāo)簽定庵。同時我們用react router v4里的Link
和NavLink
組件。
const BaseLayout = () => (
<div className="base">
<header>
<p>React Router v4 Browser Example</p>
<nav>
<ul>
<li><Link ="/">Home</Link></li>
<li><Link ="/about">About</Link></li>
<li><Link ="/me">Profile</Link></li>
<li><Link ="/login">Login</Link></li>
<li><Link ="/register">Register</Link></li>
<li><Link ="/contact">Contact</Link></li>
</ul>
</nav>
</header>
<div className="container">
<Route path="/" exact component={HomePage} />
<Route path="/about" component={AboutPage} />
<Route path="/contact" component={ContactPage} />
<Route path="/login" component={LoginPage} />
<Route path="/register" component={RegisterPage} />
<Route path="/me" component={ProfilePage} />
</div>
<footer>
React Router v4 Browser Example (c) 2017
</footer>
</div>
);
const HomePage = () => <div>This is a Home Page</div>
const LoginPage = () => <div>This is a Login Page</div>
const RegisterPage = () => <div>This is a Register Page</div>
const ProfilePage = () => <div>This is a Profile Page</div>
const AboutPage = () => <div>This is a About Page</div>
const ContactPage = () => <div>This is a Contact Page</div>
寫App
組件
const App = () => (
<BrowserRouter>
<BaseLayout />
</BrowserRouter>
)
render(<App />, document.getElementById('root'));
非排他的路由
在上例中踪危,我們在HomePage
組件的路由里使用了屬性exact
蔬浙。
<Route path="/" exact component={HomePage} />
這是因為v4中的路由默認(rèn)都是非排他的,這一點和v3的實現(xiàn)思路截然不同贞远。如果沒有exact
屬性畴博,HomePage
組件和其他的組件就會同事繪制在頁面上。
如蓝仲,當(dāng)用戶點了登錄連接以后俱病,"/"
和"/login"
都滿足匹配條件官疲,對應(yīng)的登錄組件和Home組件就會同時出現(xiàn)在界面上。但是亮隙,這不是我們期待的結(jié)果途凫,所以我們要給"/"
path加上exact
屬性。
現(xiàn)在我們來看看非排他的路由有什么優(yōu)點溢吻。假如我們有一個子菜單組件需要顯示在profile頁面出現(xiàn)的時候也出現(xiàn)维费。我們可以簡單的修改BasicLayout
來實現(xiàn)。
const BaseLayout = () => (
<div className="base">
<header>
<p>React Router v4 Browser Example</p>
<nav>
<ul>
<li><Link to="/">Home</Link></li>
<li><Link to="/about">About</Link></li>
<li>
<Link to="/me">Profile</Link>
<Route path="/me" component={ProfileMenu} />
</li>
{/*略*/}
</ul>
</nav>
</header>
</div>
);
這樣我們就會看到對應(yīng)于"/me"
路徑的組件都繪制出來了促王。這就是非排他路由的好處犀盟。
排他路由
排他路由是react router v3的默認(rèn)實現(xiàn)。只有第一個匹配的路由對應(yīng)的組件會被繪制硼砰。這一點也可以用react router v4的Switch
組件來實現(xiàn)且蓬。在Switch
組件中,只有第一個匹配的路由<Route>
或者<Redirect>
會被繪制:
import { Switch, Route } from 'react-router';
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/about" component={AboutPage} />
<Route path="me" component={ProfilePage} />
<Route component={NotFound} />
</Switch>
瀏覽器歷史
react router v4中题翰,提供了一個history
對象恶阴。這個對象包含了多個api,可以用來操作瀏覽器歷史等豹障。
你也可以在React應(yīng)用里使用history
對象的方法:
history.push("/my-path")
history.replace("/my-path")
用另外的方法可以寫成:
<Link to="/my-path" />
<Redirect to="my-path" />
使用< Redirect >組件實現(xiàn)重定向
無論何時你要重定向到另外一個地址的時候冯事,都可以使用Redirect
組件:
<Redirect to {{
pathname: '/register',
search: '?utm=something',
state: { referrer: someplage.com }
}}>
或者,更為簡單的:
<Redirect to="register" />