【全棧React】第17天: 客戶端路由

本文轉載自:衆成翻譯
譯者:iOSDevLog
連接:http://www.zcfy.cc/article/3815
原文:https://www.fullstackreact.com/30-days-of-react/day-17/react

大多數(若是不是所有)咱們的應用將在咱們的單頁應用中有多個視圖。讓咱們直接使用React Router爲咱們的應用建立多個視圖。git

咱們已經作了16天了!輕拍你的後背.....。但不是過久, 還有不少。github

如今, 咱們的應用被限制在一個單一的頁面。發現任何顯示單個視圖的複雜應用都很是少見。例如, 應用可能有一個登陸視圖, 用戶能夠在其中登陸, 或者搜索結果頁顯示用戶的搜索結果列表。這兩種不一樣的視圖具備兩種不一樣的頁面結構。npm

讓咱們看看咱們如何能夠改變與咱們的應用今天。瀏覽器

咱們將使用很是流行的 react-router 庫來處理不一樣的連接。爲了使用react-router 庫, 咱們須要使用 npm 包管理器來安裝它:服務器

npm install --save react-router-dom

安裝了react-router , 咱們將從庫中導入一些軟件包, 並更新咱們的應用體系結構。在咱們作這些更新以前, 讓咱們退後一步, 從高層看 howwhy 咱們以這種方式構建咱們的應用。react-router

從概念上講, 咱們已經看到了如何使用組件和嵌套組件來建立樹結構。使用帶有路由的單個頁面應用的這個視角(perspective), 咱們能夠將頁面的不一樣部分視爲子級。從這個角度來看, 單頁應用中的路由是這樣一種想法, 即咱們可使用一個子樹的一部分並將它與另外一個子樹進行切換。而後, 咱們能夠 動態 在瀏覽器中切換出不一樣的樹。dom

換言之_, 咱們將定義一個React組件, 它充當可路由元素的 _根 組件。而後, 咱們能夠告訴React改變一個視圖, 它能夠只是交換一個整個React組件爲另外一個, 雖然它是一個徹底不一樣的頁面渲染的服務器。函數

咱們將採起咱們的App 組件, 並定義全部不一樣的路由, 咱們能夠在咱們的應用在這個 App 組件。咱們須要從react-router 包中提取一些組件。咱們將用於設置此結構的這些組件以下:this

<BrowserRouter /> / <Router />

這是咱們用來定義 或路由樹的組件。<BrowserRouter />組件是一個組件, 其中React將在每一個路由的基礎上取代它的孩子。

<Route />

咱們將使用<Route />組件在 url 的特定位置建立可用的路由。<Route />組件 安裝在與路由配置 屬性 中設置的特定路由匹配的頁面 url 中。

一箇舊的、兼容的處理客戶端導航的方法是使用表示應用端點的 # (hash) 標記。咱們將使用此方法。咱們須要導入這個對象來告訴瀏覽器這就是咱們想要處理導航的方式。

從咱們建立了幾天前的根目錄的應用, 讓咱們更新咱們的 src/App.js 來導入這些模塊。咱們將使用不一樣的名稱語法經過 ES6 導入 BrowserRouter :

import React from 'react';

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

export class App extends React.Component {

  render() {
    <Router>
      {/* routes will go here */}
    </Router>
  }

}

如今, 讓咱們在 DOM 中使用在render()函數中導入的 <Router />組件定義路由根,。咱們將定義使用 history 屬性的路由類型。在本例中, 咱們將使用廣泛兼容的哈希歷史類型:

export class App extends React.Component {
  // ...
  render() {
    <Router>
      {/* routes will go here */}
    </Router>
  }
  // ...
}

如今, 讓咱們定義咱們的第一條路由。要定義一個路由, 咱們將使用 <Route />組件從react-router 導出, 並傳遞給它的幾個屬性:

  • path - 要激活的路由的路徑

  • component -定義路由視圖的組件

讓咱們在根路徑 / 中定義路由, 並使用只顯示一些靜態內容的無狀態組件:

const Home = () => (<div><h1>Welcome home</h1></div>)
  // ...
class App extends React.Component {
  render() {
    return (
      <Router>
        <Route path="/" component={Home} />
      </Router>
    )
  }
}

在瀏覽器中加載此頁, 咱們能夠看到咱們在根 url 處獲得了一個路由。不是很令人激動。讓咱們添加第二條在/about URL 中顯示關於頁面的路由。

const Home = () => (<div><h1>Welcome home</h1></div>)
  // ...
class App extends React.Component {
  render() {
    return (
      <Router>
        <div>
          <Route path="/" component={Home} />
          <Route path="/about" component={About} />
        </div>
      </Router>
    )
  }
}

在咱們看來, 咱們須要添加一個連接 (或一個錨標記- <a />), 使咱們的用戶能夠自由地在兩個不一樣的路由之間旅行。可是, 使用 <a />標記將告訴瀏覽器處理路由, 就像服務器端路由同樣。相反, 咱們須要使用一個不一樣的組件 (意外), 稱爲: <Link />

<Link />組件須要一個稱爲to的屬性, 指向要渲染的客戶端路由。讓咱們更新 HomeAbout組件以使用Link:

const Home = () => (<div><h1>Welcome home</h1><Link to='/about'>Go to about</Link></div>)
const About = () => (<div><h1>About</h1><Link to='/'>Go home</Link></div>)

等一下...... 咱們不太但願 二個路由都 出現。發生這種狀況的緣由是, 響應路由器將渲染與路徑匹配的 全部 內容 (除非另有指定)。對於這種狀況, 響應路由器爲咱們提供了 Switch組件。

<Switch />組件將 渲染它發現的第一個匹配 route_。讓咱們更新組件以使用 Switch組件。因爲響應路由器將嘗試渲染 _兩個 組件, 所以咱們須要指定咱們只但願根組件上的 "精確" 匹配。

const Home = () => (<div><h1>Welcome home</h1><Link to='/about'>Go to about</Link></div>)
  // ...
class App extends React.Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route path="/about" component={About} />
          <Route path="/" component={Home} />
        </Switch>
      </Router>
    )
  }
}

顯示視圖

雖然這是一個有限的介紹, 咱們不能離開討論的處理react路由器, 而不談咱們能夠獲得不一樣的方式來渲染子組件。

咱們已經看到了最簡單的方式可能, 使用 component 屬性, 但有一個更強大的方法使用的屬性稱爲renderrender屬性預計將是一個函數, 將在match 對象連同location 和路由配置時調用。

render 屬性容許咱們渲染 不管什麼 咱們想要在一個路由, 其中包括渲染其餘路由。很漂亮吧?讓咱們來看看這個動做:

const Home = () => (<div><h1>Welcome home</h1><Link to='/about'>Go to about</Link></div>)
const About = ({ name }) => (<div><h1>About {name}</h1></div>)
  // ...
class App extends React.Component {
  render() {
    return (
      <Router>
        <Switch>
          <Route
            path="/about"
            render={(renderProps) => (
              <div>
                <Link to='/about/ari'>Ari</Link>
                <Link to='/about/nate'>Nate</Link>
                <Route
                  path="/about/:name"
                  render={(renderProps) => (
                    <div>
                      <About name={renderProps.match.params.name} />
                      <Link to='/'>Go home</Link>
                    </div>
                  )} />
              </div>
            )} />
          <Route
            path="/"
            render={(renderProps) => (
              <div>
                Home is underneath me
                <Home {...this.props} {...renderProps} />
              </div>
            )} />
        </Switch>
      </Router>
    )
  }
}

如今咱們的應用中有多個頁面。咱們已經研究瞭如何經過嵌套組件來渲染這些路由, 其中僅有幾個來自react-router 的導出。

react-router 提供了這麼多的功能, 咱們沒有時間來彌補在咱們的快速介紹路由。有關詳細信息, 可查看下面鏈接:

明天, 咱們將開始與再現的整合。下面是咱們開始集成更復雜數據處理的地方。

相關文章
相關標籤/搜索