首頁>技術>

React是一個用於構建使用者介面的JavaScript庫。我們還可以藉助React Router將其擴充套件為構建多頁應用程式。這是一個第三方庫,可在我們的React應用程式中啟用路由。

在本教程中,我們將介紹使用React Router入門所需的一切。

初始化專案

為了能夠繼續學習,您需要通過在終端中執行以下命令來建立一個新的react應用程式:

npx create-react-app react-router-guide

然後,將這些程式碼行新增到App.js檔案中。

在App.js中,

然後,在繼續之前,我們先回答一個重要問題:什麼是路由?

什麼是路由?

路由是向用戶顯示不同頁面的能力。這意味著它可以通過輸入URL或單擊元素在應用程式的不同部分之間移動。

如您所知,預設情況下,React不帶路由。為了在我們的專案中啟用它,我們需要新增一個名為react-router的庫。

要安裝它,您將必須在終端中執行以下命令:

yarn add react-router-domornpm install react-router-dom

現在,我們已經成功安裝了react router,讓我們在下一部分開始使用它。

設定路由

要在React應用中啟用路由,我們首先需要從react-router-dom匯入BrowserRouter。

App.js

它會將需要路由的所有內容儲存在我們的應用程式中。這意味著,如果需要在整個應用程式中進行路由,則必須使用BrowserRouter包裝更高層的元件。

順便說一句,您不必像我在這裡那樣將BrowserRouter重新命名為Router,我只是想保持可讀性。

只有router,還做不了很多事情,讓我們在下一節中新增一條路由。

渲染路由

要渲染路由,我們必須從react-router-dom包中匯入Route元件。

然後,將其新增到我們要呈現內容的位置。路線元件具有多個屬性。但是在這裡,我們只需要路徑和渲染。

path:這是route的路徑。在這裡,我們使用 / 定義主頁的路徑。render:到達路由時將顯示內容。在這裡,我們將向用戶呈現歡迎訊息。

在某些情況下,提供這樣的路由是完全可以的,但請想象一下,當我們需要處理真實​​元件時,使用render可能不是正確的解決方案。

那麼,我們該如何顯示一個真實的元件呢?好吧,Route元件還有另一個名為component的屬性。

讓我們對示例進行一些更新以了解其實際效果。

App.js

現在,我們的路由將不再載入訊息,而是載入Home元件。

為了獲得React Router的全部功能,我們需要有多個頁面和連結可以使用。我們已經有了頁面(如果需要,也可以使用元件),現在,讓我們新增一些連結以能夠在頁面之間進行切換。

使用連結切換頁面

要新增到我們專案的連結,我們將再次使用React Router。

App.js

import React, { Fragment } from "react";import "./index.css"import { BrowserRouter as Router, Route, Link } from "react-router-dom";export default function App() {  return (    <Router>      <main>        <nav>          <ul>            <li><Link to="/">Home</Link></li>            <li><Link to="/about">About</Link></li>            <li><Link to="/contact">Contact</Link></li>          </ul>        </nav>        <Route path="/" exact component={Home} />        <Route path="/about"  component={About} />        <Route path="/contact"  component={Contact} />      </main>    </Router>  );}const Home = () => (  <>    <h1>Home</h1>    <FakeText />  </>);const About = () => (  <>    <h1>About</h1>    <FakeText />  </>);const Contact = () => (  <>    <h1>Contact</h1>    <FakeText />  </>);

匯入連結後,我們必須稍微更新導航欄。

現在,React Router不再使用標籤和href,而是使用Link來進行切換,而無需重新載入頁面。

然後,我們需要新增兩條新路線:“關於”和“聯絡方式”,以便您也可以在頁面或元件之間進行切換。

現在,我們可以通過連結轉到應用程式的不同部分。但是,我們的路由器存在問題。即使我們切換到其他頁面,Home元件也會一直顯示。

原因是React Router將檢查定義的路徑是否以/開頭(如果是),它將呈現元件。

在這裡,我們的第一個路徑以/開頭,因此Home元件每次都會呈現。

但是,我們仍然可以通過將exact屬性新增到R​​oute來更改預設行為。

App.js

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

現在,對home元件的路由添加了exact屬性,那麼只有與完整路徑匹配時才會呈現。

我們仍然可以通過用Switch包裝路由來告訴React Router一次只加載一條路由來增強它。

App.js

import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";  <Switch>    <Route path="/" exact component={Home} />    <Route path="/about"  component={About} />    <Route path="/contact"  component={Contact} />  </Switch>

現在,我們有了新的連結,讓我們使用它們來傳遞引數。

傳遞路由引數

要在頁面之間傳遞資料,我們需要更新示例。

App.js

import React, { Fragment } from "react";import "./index.css"import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";export default function App() {  const name = 'John Doe'  return (    <Router>      <main>        <nav>          <ul>            <li><Link to="/">Home</Link></li>            <li><Link to={`/about/${name}`}>About</Link></li>            <li><Link to="/contact">Contact</Link></li>          </ul>        </nav>      <Switch>        <Route path="/" exact component={Home} />        <Route path="/about/:name" component={About} />        <Route path="/contact" component={Contact} />      </Switch>      </main>    </Router>  );}const Home = () => (  <>    <h1>Home</h1>    <FakeText />  </>);const About = ({ match: { params: { name } } }) => (  // props.match.params.name  <>    <h1>About {name}</h1>    <FakeText />  </>);const Contact = () => (  <>    <h1>Contact</h1>    <FakeText />  </>);

如您在此處看到的,我們首先宣告一個新的常量名稱,該常量名稱將作為引數傳遞給About頁面。並且,我們將名稱附加到相應的連結。

這樣,我們現在必須通過調整其路徑以將名稱接收為引數path =“ / about /:name”來更新About路線。

現在,引數將作為About元件中的props接收,我們現在唯一要做的就是對props進行結構分解並獲取name屬性。順便說一下,{match:{params:{name}}}與props.match.params.name相同。

到目前為止,我們已經做了很多工作,但是,在某些情況下,我們不想使用連結在頁面之間導航。

有時,我們必須等待操作完成才能導航到下一頁。

讓我們在下一部分中處理這種情況。

以程式設計方式導航

我們收到的props有一些便捷的方法可用於在頁面之間導航。

App.js

const Contact = ({history}) => (  <>    <h1>Contact</h1>    <button onClick={() => history.push('/') } >Go to home</button>    <FakeText />  </>);

在這裡,我們從收到的props中提取history物件。它有一些方便的方法,例如goBack,goForward等。但是在這裡,我們將使用push方法來轉到主頁。

現在,讓我們處理重定向使用者的情況。

重定向到另一個頁面

React Router還有另一個名為Redirect的元件,正如您猜到的,它可以幫助我們將使用者重定向到另一個頁面。

import { BrowserRouter as Router, Route, Link, Switch, Redirect } from "react-router-dom";const About = ({ match:{ params: { name } } }) => (  // props.match.params.name  <>    { name !== 'Foo' ? <Redirect to="/" /> : null }    <h1>About {name}</h1>    <FakeText />  </>);

現在,如果作為引數傳遞的名稱不等於Foo,則使用者將被重定向到主頁。

您可能會爭論為什麼我不使用props.history.push('/')重定向使用者?好吧,Redirect元件會替換頁面,因此使用者無法返回上一頁,但是使用push方法,它可以。同樣,您還可以使用props.history.replace('/')來模仿重定向行為。

現在,讓我們繼續處理使用者遇到不存在的路由時的情況。

重定向到404頁面

要將使用者重定向到404頁面,您可以建立一個元件來顯示它,但是為了使事情簡單起見,我將僅顯示帶有render的訊息。

import React, { Fragment } from "react";import "./index.css"import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";export default function App() {  const name = 'Foo'  return (    <Router>      <main>        <nav>          <ul>            <li><Link to="/">Home</Link></li>            <li><Link to={`/about/${name}`}>About</Link></li>            <li><Link to="/contact">Contact</Link></li>          </ul>        </nav>      <Switch>        <Route path="/" exact component={Home} />        <Route path="/about/:name"  component={About} />        <Route path="/contact"  component={Contact} />        <Route render={() => <h1>404: page not found</h1>} />      </Switch>      </main>    </Router>  );}

我們新增的新路由將捕獲所有不存在的路徑,並將使用者重定向到404頁面。

現在,讓我們繼續前進,並在下一部分中學習如何保護我們的路由。

保護路由

有很多方法可以保護通往React的路由。但是,在這裡,我僅檢查使用者是否已通過身份驗證並將其重定向到適當的頁面。

import React, { Fragment } from "react";import "./index.css"import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";export default function App() {  const name = 'Foo'  const isAuthenticated = false  return (    <Router>      <main>        <nav>          <ul>            <li><Link to="/">Home</Link></li>            <li><Link to={`/about/${name}`}>About</Link></li>            <li><Link to="/contact">Contact</Link></li>          </ul>        </nav>        <Switch>          <Route path="/" exact component={Home} />          {            isAuthenticated ?               <>                <Route path="/about/:name"  component={About} />                <Route path="/contact"  component={Contact} />              </>             : <Redirect to="/" />          }        </Switch>      </main>    </Router>  );}

如您所見,我聲明了一個模仿身份驗證的變數。然後,檢查使用者是否已通過身份驗證。如果是這種情況,請渲染受保護的頁面,否則將其重定向到主頁。

到目前為止,我們已經介紹了很多內容,但是它仍然是一個有趣的部分:路由鉤子Hooks。

讓我們進入最後一節,介紹Hooks。

路由hooks(useHistory,useParams,useLocation)

路由hooks使事情變得容易得多。現在,以簡單而優雅的方式訪問歷史記錄,位置或引數。

useHistory

useHistory鉤子使我們可以訪問history物件,而無需從props中將其提取。

import { useHistory } from "react-router-dom";const Contact = () => {  const { history } = useHistory();  return (    <>      <h1>Contact</h1>      <button onClick={ () => history.push('/') } >Go to home</button>    </>  )};

useParams

它可以幫助我們無需使用props物件就可以在URL上傳遞引數。

import { BrowserRouter as Router, Route, Link, Switch, useParams } from "react-router-dom";export default function App() {  const name = 'Foo'    return (    <Router>      <main>        <nav>          <ul>            <li><Link to="/">Home</Link></li>            <li><Link to={`/about/${name}`}>About</Link></li>          </ul>        </nav>      <Switch>        <Route path="/" exact component={Home} />        <Route path="/about/:name"  component={About} />      </Switch>      </main>    </Router>  );}const About = () => {  const { name } = useParams()    return (    // props.match.params.name    <>      { name !== 'Foo' ? <Redirect to="/" /> : null }      <h1>About {name}</h1>      <Route component={Contact} />    </>  )};

useLocation

它返回代表當前URL的位置物件。

import { useLocation } from "react-router-dom";const Contact = () => {  const { pathname } = useLocation();  return (    <>      <h1>Contact</h1>      <p>當前 URL: {pathname}</p>    </>  )};
最後

React Router是一個了不起的庫,它可以幫助我們從一個頁面轉到一個多頁面的應用程式(雖然它仍然是一個頁面),並且具有很高的可用性。現在,藉助路由hooks,您已經親眼目睹了它們的簡易性和優雅性,絕對是您下一個專案中需要考慮使用的。

  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Jenkins 基礎知識大補