react-router(v4)

概要

開發單頁應用, 首先繞不開的內容就是路由, react router v4 版本是最新的版本. 和以前的版本相比, 成熟了不少, 也簡單了不少, 使用起來更加方便.javascript

核心 component

react-router V4 能夠用於 Web 和 Native. 這裏主要討論基於 Web 的應用.css

react-router 有不少 Components, 可是隻要掌握下面 3 個 Component 就能夠管理好 react 應用的路由了.html

Router component

Router 是整個應用的路由. 在 Web 應用中, 使用 BrowerRouter 來包裝 Appjava

<BrowserRouter>
  <App />
</BrowserRouter>

而後, 在 App component 中, 就可使用 Route 來定義各個路由對應的 componentreact

Route component

每一個 Route 都是一個具體的路由, 對應一個具體的頁面. Route 能夠對應一個 Component, 也能夠直接寫個匿名的 render 函數.redux

Route 中最經常使用的屬性就是 path, 也就是路由的地址, 除此以外, Route 最重要的做用是會將 { match, location, history } 3 個屬性注入到對應的 Component 或者 render 函數中.bash

Link component

Link 是用來導航的, 也就是在不一樣 Route 之間切換就會用到 Link.react-router

經常使用路由示例

示例工程

示例工程的建立採用 create-react-app 工具.app

$ create-react-app route-test
$ cd route-test
$ yarn add react-router-dom

基本使用

修改工程中的 App.js 文件, 增長 route 的 sampledom

import React, { Component } from 'react'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import './App.css'

const Index = () => <h2>Home</h2>
const About = () => <h2>About</h2>
const Users = () => <h2>Users</h2>

class App extends Component {
  render() {
    return (
      <Router>
        <div>
          <nav>
            <ul>
              <li>
                <Link to="/">Home</Link>
              </li>
              <li>
                <Link to="/about/">About</Link>
              </li>
              <li>
                <Link to="/users/">Users</Link>
              </li>
            </ul>
          </nav>

          <Route path="/" exact component={Index} />
          <Route path="/about/" component={About} />
          <Route path="/users/" component={Users} />
        </div>
      </Router>
    )
  }
}

export default App

這個示例中, 就包含了 3 個經常使用組件 Router, Route 和 Link

路由參數

路由的參數能夠加在 path 上, 下面的示例中, Users Component 能夠經過注入的 match 來獲得 URL 中的參數.

import React, { Component } from 'react'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import './App.css'

const Index = () => <h2>Home</h2>
const About = () => <h2>About</h2>
const Users = ({ match }) => (
  <h2>
    User is {match.params.name}, age: {match.params.age}
  </h2>
)

class App extends Component {
  render() {
    return (
      <Router>
        <div>
          <nav>
            <ul>
              <li>
                <Link to="/">Home</Link>
              </li>
              <li>
                <Link to="/about/">About</Link>
              </li>
              <li>
                <Link to="/users/test/16">Users</Link>
              </li>
            </ul>
          </nav>

          <Route path="/" exact component={Index} />
          <Route path="/about/" component={About} />
          <Route path="/users/:name/:age" component={Users} />
        </div>
      </Router>
    )
  }
}

export default App

query 參數

除了上面那種 RESTful 的參數方式, 也能夠經過 query 來傳遞參數. 下例中, 經過 location.search 來獲取 querystring, 至於解析 querystring, 已有不少現成的方法可使用.

import React, { Component } from 'react'
import { BrowserRouter as Router, Route, Link } from 'react-router-dom'
import './App.css'

const Index = () => <h2>Home</h2>
const About = ({ match, location }) => (
  <h2>About's search string: {location.search}</h2>
)
const Users = ({ match }) => (
  <h2>
    User is {match.params.name}, age: {match.params.age}
  </h2>
)

class App extends Component {
  render() {
    return (
      <Router>
        <div>
          <nav>
            <ul>
              <li>
                <Link to="/">Home</Link>
              </li>
              <li>
                <Link to={{ pathname: '/about/', search: '?name=test&age=16' }}>
                  About
                </Link>
              </li>
              <li>
                <Link to="/users/test/16">Users</Link>
              </li>
            </ul>
          </nav>

          <Route path="/" exact component={Index} />
          <Route path="/about/" component={About} />
          <Route path="/users/:name/:age" component={Users} />
        </div>
      </Router>
    )
  }
}

export default App

FAQ

在剛開始使用 react-router 時, 可能會有些疑問, 我整理了本身在使用中一些疑惑:

match 是如何注入到 Component 中的

match, location, history 這 3 個 object, 是由 Route Component 做爲 props 注入到它的 render 方法, 或者 component={xxx} prop 對應的組件中的

match.path 和 match.url 有什麼區別

  • match.path 是用來作匹配用的, 也就是在 Route 中使用的
  • match.url 是用來遷移頁面用的, 也就是在 Link 中使用的

好比上面的例子中, 對於 /users

  • match.path 是 users:name/:age
  • match.url 是 /users/test/16

BrowserRouter 和 HashRouter 有什麼區別

  • BrowserRouter 是用於和 Server 有交互的 Router
  • HashRouter 是用於靜態文件服務的 Router

Route 和 Switch 的區別

當有多個 Route 並列時, 若是外層沒有包裹 Switch, 那麼匹配到的 Route 都會被 render, 若是有 Switch, 那麼只會 render 第一個匹配上的 Route

Route 若是不設置 path, 則每次都會匹配成功

Link 和 NavLink 的區別

NavLink 是一種特殊的 Link, 它能夠設置一些 active 時的樣式.

路由信息和 redux 狀態管理如何結合

路由信息本質上也是一種狀態信息, 放不放在 redux 中來管理, 相信不少人都會糾結. 官方的建議是不要把路由的狀態放在 redux 的 store 中來管理, 理由以下:

  1. 路由狀態通常只有 Components 才關心, 無論放不放在 redux 中, Component 的代碼不會有什麼改變
  2. 大部分狀況下, 路由跳轉都是經過 Link, NavLink, Redirct 來完成, 若是須要經過代碼, 或者異步 action 中來跳轉, 能夠經過傳入 history 對象來完成.
  3. 路由變化通常不須要經過時間旅行(time travel, redux 的一個調試工具)來 debug.
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息