React-router v4教程

在這個教程裏,咱們會從一個例子React應用開始學習react-router-dom。其中你會學習如何使用LinkNavLink等來實現跳轉,Switchexact實現排他路由和瀏覽器路徑歷史。javascript

也許學習react-router最好的辦法就是用react-router-dom v4來寫一個多頁的react應用。這個react應用會包含登陸、註冊、首頁、聯繫人等頁面。可是,首先讓咱們來看一下react router v4的概念,以及它與v3有什麼不一樣的地方。html

React router v4 vs v3

v4是react router的一次重寫,因此和v3有不少不一樣的地方。主要有:java

  • 在react router v4裏,路由再也不是集中在一塊兒的。它成了應用佈局、UI的一部分。
  • 瀏覽器用的router在react-router-dom裏。因此,瀏覽器裏使用的時候只須要import react-router-dom就能夠。
  • 新的概念BrowerRouterHashRouter。他們各自服務於不一樣的情景下。詳見下文。
  • 不在使用{props.children}來處理嵌套的路由。
  • v4的路由默認再也不排他,會有多個匹配。而v3是默認排他的,只會有一個匹配被使用。

react-router-dom是react-router中用於瀏覽器的。react-router被分爲一下幾部分:react

  • react-router是瀏覽器和原生應用的通用部分。
  • react-router-dom是用於瀏覽器的。
  • react-router-native是用於原生應用的。

React-router vs react-router-dom vs react-router-native

react-router是核心部分。react-router-dom提供了瀏覽器使用須要的定製組件。react-router-native則專門提供了在原生移動應用中須要用到的部分。因此,若是在本例中實現瀏覽器開發就只須要安裝react-router-domgit

安裝

如上所說,咱們使用react開發web應用,因此只須要安裝react-router-domgithub

npm install react-router-dom --save

理解和使用react-router

  • BrowserRouter,這是對Router接口的實現。使得頁面和瀏覽器的history保持一致。如:window.location
  • HashRouter,和上面的同樣,只是使用的是url的hash部分,好比:window.location.hash
  • MemoryRouter
  • NativeRouter,處理react native內的路由。
  • StaticRouter,處理靜態路由,和v3同樣。

BrowserRouter vs HashRouter

在react-router的各類router中,<BrowserRouter><HashRouter>是能夠在瀏覽器中使用的。若是你使用的是一個非靜態的站點、要處理各類不一樣的url那麼你就須要使用BrowserRouter。相反的若是你的server只處理靜態的url,那麼就使用HashRouterweb

理解和使用Route

組件是react router v4裏最有用的組件。背後的使用哲學也很簡單,不管什麼時候你須要在匹配某個路徑的時候繪製一個組件,那麼就可使用 Route組件。 npm

Route組件可使用以下的屬性:api

  • path屬性,字符串類型,它的值就是用來匹配url的。
  • component屬性,它的值是一個組件。在path匹配成功以後會繪製這個組件。
  • exact屬性,這個屬性用來指明這個路由是否是排他的匹配。
  • strict屬性, 這個屬性指明路徑只匹配以斜線結尾的路徑。

還有其餘的一些屬性,能夠用來代替component屬性。瀏覽器

  • render屬性,一個返回React組件的方法。傳說中的rencer-prop就是從這裏來的。
  • children屬性,返回一個React組件的方法。只不過這個老是會繪製,即便沒有匹配的路徑的時候。

多數的時候是用component屬性就能夠知足。可是,某些狀況下你不得不使用renderchildren屬性。

  • match
  • location
  • history

如:
使用組件:

<Route exact path="/" component={HomePage} />

使用render屬性實現內聯繪製:

<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>
  )} />
)

更多關於react-router v4如何匹配路徑的內容,請移步這裏

URL / Path / Route的參數

一般狀況下,咱們都會在路徑裏添加參數。這樣方便在不一樣的組件之間傳遞一些必要的數據。那麼咱們如何才能獲取到這些傳遞的參數,並傳遞給組件中呢?咱們只須要在路徑的最後加上/:param。如:

<Route path="/:param1" component={HomePage} />

const HomePage = ({match}) => (
  <div>
    <h1> parameter => {match.params.param1}
  </div>
);

一旦有路徑能夠匹配成功,那麼就會穿件一個擁有以下屬性的對象,並傳入繪製的組件裏:

  • 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。

NavLinkLink的一個子類,在Link組件的基礎上增長了繪製組件的樣式,好比:

<NavLink to="/me" activeStyle={{SomeStyle}} activeClassName="selected">
  My Profile
</NavLink>

使用react router dom實現你的第一個demo

如今咱們用react router dom來實現第一個demo。

首先,引入必要的組件。好比:RouteBrowserRouter

import { BrowserRouter, Route } from 'react-router-dom';

接下來,咱們建立一些組件和一些Html標籤。同時咱們用react router v4裏的LinkNavLink組件。

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'));

如你所見,react router v4的組件還很是的易用的。

理解和使用非排他的路由

在上例中,咱們在HomePage組件的路由裏使用了屬性exact

<Route path="/" exact component={HomePage} />

這是由於v4中的路由默認都是非排他的,這一點和v3的實現思路大相徑庭。若是沒有exact屬性,HomePage組件和其餘的組件就會同事繪製在頁面上。

如,當用戶點了登陸鏈接之後,"/""/login"都知足匹配條件,對應的登陸組件和Home組件就會同時出如今界面上。可是,這不是咱們期待的結果,因此咱們要給"/"path加上exact屬性。

如今咱們來看看非排他的路由有什麼優勢。假如咱們有一個子菜單組件須要顯示在profile頁面出現的時候也出現。咱們能夠簡單的修改BasicLayout來實現。

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>
);

這樣咱們就會看到對應於"/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組件,這些主鍵只要包含pathcomponent屬性。不管什麼時候有了匹配的路由,那麼它就會進行非排他的繪製(全部匹配的路由都會繪製)。你也能夠把Route放在Switch組件裏來實現排他的繪製(只有第一個匹配的路由會被繪製)。你能夠在路徑中傳遞參數,match對象會保留這些參數。最後,全部在web中使用的路由組件都包含在react-router-dom中。只須要引入react-router-dom就可使用。

原文地址:https://www.techiediaries.com/react-router-dom-v4/

相關文章
相關標籤/搜索