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 是用來導航的, 也就是在不一樣 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, 則每次都會匹配成功

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

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

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

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