React Router v6 使用指南

本文首發於公衆號《前端全棧開發者》,第一時間閱讀最新文章,會優先兩天發表新文章。關注後私信回覆:大禮包,送某網精品視頻課程網盤資料,準能爲你節省很多錢!

在本教程中,讓咱們看一下如何使用React Router v6庫建立路由。請注意,在撰寫本文時,React Router v6仍處於測試階段。本教程將帶你一窺該庫即將推出的一些新功能。javascript

若是你有在React應用程序中使用路由的經驗,你可能已經知道在過去的幾年裏Reach Router已經引發了必定的關注,可是,它從版本6開始被合併回React Router庫。這意味着v6版本比以前的版本有更小的包大小,這是Reach Router存在的主要緣由之一。html

先決條件

爲了充分利用本教程,請確保你在本地開發環境中安裝瞭如下內容。前端

  • Node.js版本 >= 12.x.x
  • 軟件包管理器,例如npm或yarn或npx
  • JavaScript,React.js和React Hooks的基礎知識

入門

首先建立一個新的React應用。從終端窗口使用下面的命令生成項目目錄,而後在項目目錄內導航,安裝所需的依賴項,添加React Router v6庫。java

npx create-react-app react-router-v6-example
cd react-router-v6-example
yarn add history react-router-dom@next
爲了方便,我使用 codesandbox.io 做爲演示,像這樣的Demo代碼推薦使用 codesandbox.io 這樣在線的IDE工具

一旦安裝了依賴關係,在你喜歡的代碼編輯器中打開 package.json 文件,你會看到 react-router-dom 庫的依賴版本。react

「dependencies": {
  // 安裝的其他依賴項
  "react-router-dom": "6.0.0-beta.0",
},

React Router庫中的不一樣軟件包

React Router庫包含三個不一樣的npm包,如下每一個包都有不一樣的用途。git

  • react-router
  • react-router-dom
  • react-router-native

程序包 react-router 是核心庫,用做上面列出的他兩個程序包的對等依賴項。react-router-dom 是React應用中用於路由的軟件包。列表中的最後一個包,react-router-native 有用於開發React Native應用的綁定。github

如今咱們有了這些,讓咱們創建第一個路由。web

使用React Router v6建立第一個路由

要使用React Router庫建立第一個路由,打開 src/App.js 文件,添加如下導入語句。npm

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

這是從 react-router-dom 庫導入的第一個組件。它用於包裝不一樣的路線,它使用HTML5 history API來跟蹤React應用程序中的路由歷史記錄。json

上面片斷中的 Router 部分是別名,使編寫起來更容易。建議在React應用的組件層次結構中的頂級組件上導入和使用它:

function App() {
  return <Router>{/* 全部路由都嵌套在其中 */}</Router>;
}

react-router-dom 導入的下一個組件是新的 Routes

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

這個新的元素是之前 Switch 組件的升級版,它包括相對路由和連接、自動路由排名、嵌套路由和佈局等功能。

所需的 react-router-dom 中的最後一個組件稱爲 Route,它負責渲染React組件的UI。它有一個稱爲 path 的屬性,該屬性始終與應用程序的當前URL匹配。 第二個須要的屬性叫作 element,當遇到當前的URL時,會告訴 Route 組件要渲染哪一個React組件。這裏的 element 鍵字也是新增長的,此前,在React Router v5中,你會使用名爲 component 的屬性。

爲了在下面的演示中建立第一個路由,讓咱們建立一個名爲 Home 的基本函數組件,返回一些JSX。

function Home() {
  return (
    <div style={{ padding: 20 }}>
      <h2>Home View</h2>
      <p>在React中使用React Router v6 的指南</p>
    </div>
  );
}

使用如下路由更新 App 函數組件。這裏須要注意的v6庫的另外一個特色是,Route 組件的 element 屬性如今容許你傳遞一個React組件,而不只僅是該React組件的名稱。這樣就能夠很方便的把屬性傳到路由上:

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
      </Routes>
    </Router>
  );
}

要查看它是否正常工做,請返回到終端窗口,並使用命令 yarn start 啓動開發服務器。接下來,在瀏覽器窗口中訪問URL http://localhost:3000。

這是此步驟以後的輸出:

讓咱們快速建立另外一個名爲 About 的函數組件,只有當瀏覽器窗口中的URL爲http://localhost:3000/about時纔會呈現。

function About() {
  return (
    <div style={{ padding: 20 }}>
      <h2>About View</h2>
      <p>在React中使用React Router v6 的指南</p>
    </div>
  );
}

而後,爲 About 組件添加 Route

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
</Routes>

如今,返回瀏覽器窗口並訪問URL http://localhost:3000/about:

添加導航菜單

爲了在React應用程序內的特定路由或演示應用程序中現有的兩個路由上導航,讓咱們在 react-router-domLink 組件的幫助下添加一個最小的導航欄。

首先從庫中導入它:

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

在HTML中的不一樣網頁之間導航的概念是使用錨點標記:

<a href="">Some Link Name</a>

在React應用程序中使用這種方法將致使在每次渲染新視圖或頁面自己時刷新web頁面。爲了不刷新網頁,react-router-dom 庫提供了 Link 組件。

接下來,在 App 函數組件內部,建立一個導航欄,如代碼片斷所示:

<Router>
  <nav style={{ margin: 10 }}>
    <Link to="/" style={{ padding: 5 }}>
      Home
    </Link>
    <Link to="/about" style={{ padding: 5 }}>
      About
    </Link>
  </nav>
  {/* 其他代碼保持不變 */}
</Router>

到瀏覽器窗口,以查看正在運行的導航欄:

如何處理嵌套路由

嵌套路由是一個很重要的概念,須要理解。當路由被嵌套時,通常認爲網頁的某一部分保持不變,只有網頁的子部分發生變化。

例如,若是你訪問一個簡單的博客,則始終顯示該博客的標題,而後在其下方顯示一個博客文章列表。可是,當你單擊博客文章時,博客文章列表將替換爲該特定博客文章的內容或描述。這是本節將要執行的示例,以瞭解如何在最新版本的React Router庫中處理嵌套路由。

在React Router v5中,必須明肯定義嵌套路由,React Router v6並不是如此。它從React Router庫中挑選了一個名爲 Outlet 的最佳元素,爲特定路由呈現任何匹配的子元素。首先,從 react-router-dom 庫中導入 Outlet

import { Outlet } from 'react-router-dom';

爲了模仿基本博客,咱們在 App.js 文件中添加一些模擬數據。該代碼段包含一個稱爲 BlogPosts 的對象,該對象進一步包含不一樣的對象做爲屬性。每一個對象都由三部分組成:

  • 一個惟一的ID
  • 文章的標題
  • 文章的描述
const BlogPosts = {
  '1': {
    title: 'First Blog Post',
    description: 'Lorem ipsum dolor sit amet, consectetur adip.'
  },
  '2': {
    title: 'Second Blog Post',
    description: 'Hello React Router v6'
  }
};

這個獨特的片斷將被用於web瀏覽器的URL中,以查看每一個帖子的內容。接下來,建立一個名爲 Posts 的函數組件,其中顯示全部博客帖子的列表:

function Posts() {
  return (
    <div style={{ padding: 20 }}>
      <h2>Blog</h2>
      {/* 渲染任何匹配的子級 */}
      <Outlet />
    </div>
  );
}

定義另外一個名爲 PostLists 的組件,只要瀏覽器窗口中的URL點擊http://localhost:3000/posts,就會顯示全部文章的列表。讓咱們使用JavaScript Object.entry() 方法從對象 BlogPosts 中返回一個數組,這個數組將被映射爲顯示全部博客文章的標題列表:

function PostLists() {
  return (
    <ul>
      {Object.entries(BlogPosts).map(([slug, { title }]) => (
        <li key={slug}>
          <h3>{title}</h3>
        </li>
      ))}
    </ul>
  );
}

修改 App 函數組件中的路由,以下所示:

<Routes>
  {/* 其他代碼保持不變 */}
  <Route path="posts" element={<Posts />}>
    <Route path="/" element={<PostLists />} />
  </Route>
</Routes>

這代表每當觸發URL http://localhost:3000/posts時,將渲染博客文章列表,所以,組件 PostsLists

如何訪問路由的URL參數和動態參數

要想從渲染的博客文章列表中點擊文章標題來訪問各個文章,你要作的就是,將每一個文章的標題包裹在 PostsLists 組件中的 Link 組件內。而後,使用每一個文章的 slug 定義每一個文章的路徑,前綴爲 /posts/ 的文章在瀏覽器中的路徑是一致的。

<ul>
  {Object.entries(BlogPosts).map(([slug, { title }]) => (
    <li key={slug}>
      <Link to={`/posts/${slug}`}>
        <h3>{title}</h3>
      </Link>
    </li>
  ))}
</ul>

接下來,從 react-router-dom 庫中導入一個名爲 useParams 的鉤子。經過這個鉤子,你能夠訪問特定路由(或Slug)可能具備的任何動態參數。每一個 slug 的動態參數都會是每篇博文的 titledescription。訪問它們的須要是,當在瀏覽器窗口中以URL形式觸發博客文章的特定段時,顯示每一個博客文章的內容:

import { useParams } from 'react-router-dom';

建立一個名爲 Post 的新函數組件,該組件將從 useParams 鉤子中獲取當前的文章。使用JavaScript中的方括號符號語法,將建立一個新的 post 變量,該變量包含屬性的值或博客文章的當前內容。

function Post() {
  const BlogPosts = {
    "1": {
      title: "第一篇博客文章",
      description: "第一篇博客文章,是關於Vue3.0的"
    },
    "2": {
      title: "第二篇博客文章",
      description: "Hello React Router v6"
    }
  };
  
  const { slug } = useParams();
  const post = BlogPosts[slug];
  const { title, description } = post;
  return (
    <div style={{ padding: 20 }}>
      <h3>{title}</h3>
      <p>{description}</p>
    </div>
  );
}

最後,在 App 函數組件中添加一個稱爲 :slug 的動態路由,以渲染每一個文章的內容:

// 其他代碼保持不變
<Route path="posts" element={<Posts />}>
  <Route path="/" element={<PostLists />} />
  <Route path=":slug" element={<Post />} />
</Route>

這是此步驟以後的完整輸出:

總結

若是你是第一次學習React Router,但願這篇文章能給你提供一個很好的介紹。若是你已經熟悉這個路由庫之前的任何一個版本,我但願這篇文章能讓你瞭解之前和最新版本之間的變化。

獲取本案例完整代碼

推薦閱讀

相關文章
相關標籤/搜索