也許學習react-router最好的辦法就是用react-router-dom v4來寫一個多頁的react應用。這個react應用會包含登錄、注冊、首頁、聯系人等頁面。但是,首先讓我們來看一下react router v4的概念,以及它與v3有什么不同的地方。
v4是react router的一次重寫,所以和v3有很多不同的地方。主要有:
在react router v4里,路由不再是集中在一起的。它成了應用布局、UI的一部分。
瀏覽器用的router在react-router-dom
里。所以,瀏覽器里使用的時候只需要import react-router-dom
就可以。
新的概念BrowerRouter
和HashRouter
。他們各自服務于不同的情景下。詳見下文。
不在使用{props.children}
來處理嵌套的路由。
v4的路由默認不再排他,會有多個匹配。而v3是默認排他的,只會有一個匹配被使用。
react-router-dom
是react-router中用于瀏覽器的。react-router
被分為一下幾部分:
react-router是瀏覽器和原生應用的通用部分。
react-router-dom是用于瀏覽器的。
react-router-native是用于原生應用的。
react-router
是核心部分。react-router-dom
提供了瀏覽器使用需要的定制組件。react-router-native
則專門提供了在原生移動應用中需要用到的部分。所以,如果在本例中實現瀏覽器開發就只需要安裝react-router-dom
。
如上所說,我們使用react開發web應用,所以只需要安裝react-router-dom
。
npm install react-router-dom --save
BrowserRouter
,這是對Router
接口的實現。使得頁面和瀏覽器的history保持一致。如:window.location
。
HashRouter
,和上面的一樣,只是使用的是url的hash部分,比如:window.location.hash
。
MemoryRouter
,
NativeRouter
,處理react native內的路由。
StaticRouter
,處理靜態路由,和v3一樣。
在react-router的各種router中,<BrowserRouter>
和<HashRouter>
是可以在瀏覽器中使用的。如果你使用的是一個非靜態的站點、要處理各種不同的url那么你就需要使用BrowserRouter
。相反的如果你的server只處理靜態的url,那么就使用HashRouter
。
<Route>組件是react router v4里最有用的組件。背后的使用哲學也很簡單,無論何時你需要在匹配某個路徑的時候繪制一個組件,那么就可以使用Route
組件。
Route
組件可以使用如下的屬性:
path屬性,字符串類型,它的值就是用來匹配url的。
component屬性,它的值是一個組件。在path
匹配成功之后會繪制這個組件。
exact屬性,這個屬性用來指明這個路由是不是排他的匹配。
strict屬性, 這個屬性指明路徑只匹配以斜線結尾的路徑。
還有其他的一些屬性,可以用來代替component
屬性。
render屬性,一個返回React組件的方法。傳說中的rencer-prop就是從這里來的。
children屬性,返回一個React組件的方法。只不過這個總是會繪制,即使沒有匹配的路徑的時候。
多數的時候是用component
屬性就可以滿足。但是,某些情況下你不得不使用render
或children
屬性。
match
location
history
如:
使用組件:
<Route exact path="/" component={HomePage} />
使用render
屬性實現內聯繪制:
<Route path="/" render={()=><p>HomePage</p>} />
來看哥更復雜的:
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> )} /> )
更多關于react-router v4如何匹配路徑的內容,請移步這里。
通常情況下,我們都會在路徑里添加參數。這樣方便在不同的組件之間傳遞一些必要的數據。那么我們如何才能獲取到這些傳遞的參數,并傳遞給組件中呢?我們只需要在路徑的最后加上/:param
。如:
<Route path="/:param1" component={HomePage} /> const HomePage = ({match}) => ( <p> <h1> parameter => {match.params.param1} </p> );
一旦有路徑可以匹配成功,那么就會穿件一個擁有如下屬性的對象,并傳入繪制的組件里:
url: 匹配的url。
path:就是path。
isExact:如果path
和當前的widnow.location
的path部分完全相同的話。
params:在URL里包含的參數。
Link
是react router v4特有的一個組件。是用來代替上一版的anchor link。使用Link
可以在React應用的不同頁面之間跳轉。與unclor會重新加載整個頁面不同,Link
只會重新加載頁面里和當前url可以匹配的部分。
Link
組件需要用到to
屬性,這個屬性的值就是react router要跳轉到的地址。如:
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
也可以使用replace
屬性,如果點擊的話,那么history里的當前領會被replace。
NavLink
是Link
的一個子類,在Link組件的基礎上增加了繪制組件的樣式,比如:
<NavLink to="/me" activeStyle={{SomeStyle}} activeClassName="selected"> My Profile </NavLink>
現在我們用react router dom來實現第一個demo。
首先,引入必要的組件。比如:Route
和BrowserRouter
。
import { BrowserRouter, Route } from 'react-router-dom';
接下來,我們創建一些組件和一些Html標簽。同時我們用react router v4里的Link
和NavLink
組件。
const BaseLayout = () => ( <p 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> <p 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} /> </p> <footer> React Router v4 Browser Example (c) 2017 </footer> </p> );
然后我們來創建需要的組件:
const HomePage = () => <p>This is a Home Page</p> const LoginPage = () => <p>This is a Login Page</p> const RegisterPage = () => <p>This is a Register Page</p> const ProfilePage = () => <p>This is a Profile Page</p> const AboutPage = () => <p>This is a About Page</p> const ContactPage = () => <p>This is a Contact Page</p>
最后,寫App
組件。
const App = () => ( <BrowserRouter> <BaseLayout /> </BrowserRouter> ) render(<App />, document.getElementById('root'));
如你所見,react router v4的組件還非常的易用的。
在上例中,我們在HomePage
組件的路由里使用了屬性exact
。
<Route path="/" exact component={HomePage} />
這是因為v4中的路由默認都是非排他的,這一點和v3的實現思路截然不同。如果沒有exact
屬性,HomePage
組件和其他的組件就會同事繪制在頁面上。
如,當用戶點了登錄連接以后,"/"
和"/login"
都滿足匹配條件,對應的登錄組件和Home組件就會同時出現在界面上。但是,這不是我們期待的結果,所以我們要給"/"
path加上exact
屬性。
現在我們來看看非排他的路由有什么優點。假如我們有一個子菜單組件需要顯示在profile頁面出現的時候也出現。我們可以簡單的修改BasicLayout
來實現。
const BaseLayout = () => ( <p 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> </p> );
這樣我們就會看到對應于"/me"
路徑的組件都繪制出來了。這就是非排他路由的好處。
排他路由是react router v3的默認實現。只有第一個匹配的路由對應的組件會被繪制。這一點也可以用react router v4的Switch
組件來實現。在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應用里使用history
對象的方法:
history.push("/my-path") history.replace("/my-path")
用另外的方法可以寫成:
<Link to="/my-path" /> <Redirect to="my-path" />
無論何時你要重定向到另外一個地址的時候,都可以使用Redirect
組件:
<Redirect to {{ pathname: '/register', search: '?utm=something', state: { referrer: someplage.com } }}>
或者,更為簡單的:
<Redirect to="register" />
react router v4讓開發react應用變得更加的簡單。讓react應用內的頁面跳轉更加簡單。你只需要聲明一個BrowserRouter
或者HashRouter
,然后在它的內部放上一系列的Route
組件,這些主鍵只要包含path
和component
屬性。無論何時有了匹配的路由,那么它就會進行非排他的繪制(所有匹配的路由都會繪制)。你也可以把Route
放在Switch
組件里來實現排他的繪制(只有第一個匹配的路由會被繪制)。你可以在路徑中傳遞參數,match
對象會保留這些參數。最后,所有在web中使用的路由組件都包含在react-router-dom
中。只需要引入react-router-dom
就可以使用。
相信看了本文案例你已經掌握了方法,更多精彩請關注Gxl網其它相關文章!
推薦閱讀:
Chart.js 輕量級HTML5圖表繪制工具庫使用步驟詳解
Chart.js輕量級圖表庫使用案例解析
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com