JavaScript >> Javascript 文檔 >  >> React

將 React Router 用於單頁應用程序

React 沒有內置路由,但是我們可以通過 react-router-dom 輕鬆實現路由 圖書館。 路由 是 Web 應用程序如何引導流量。 (如果您知道什麼是路由,請隨意跳過此部分。)

示例:如果您訪問 taniarascia.com,您最終會出現在我的主頁上。如果您訪問 taniarascia.com/me,您將被重定向到我的關於我的頁面。如果您訪問 taniarascia.com/categories/javascript 或 taniarascia.com/categories/css,您最終會進入類別列表頁面。這些頁面的路由如下所示:

  • / - 根
  • /:page_id - 頁面
  • /categories/:category_id - 類別

我實際上並沒有創建一個名為 categories 的文件夾 並用一堆像 javascript.html 這樣的文件填充它 或 css.html ,我只有一個模板,路由器知道指向正確的模板。到達模板後,它可以從 URL 中提取以了解要顯示哪些變量 - 例如,JavaScript 或 CSS 相關的帖子。

該網站也恰好是一個單頁應用程序 (或 SPA) - 只加載一個頁面,每次點擊新頁面都會加載一些額外的 JSON 數據,但實際上並不像加載 index.html 那樣請求新資源 和 about-me.html 會的。

我將向你展示如何使用 react-router-dom 在 React 中設置一個簡單的 SPA ,並通過 URL 動態拉入數據。如果您在途中迷路,以下是已完成項目的來源。

  • 查看源代碼

先決條件

  • 如果您還不了解 React 或 React Hooks,請閱讀 React 入門或使用 Hooks 構建 React 應用程序。
  • 如果您根本不知道如何使用 API,請閱讀如何在 JavaScript 中連接 API。

安裝

創建一個新的 React 應用。

npx create-react-app router-example
Creating a new React app in /Users/taniarascia/dev/sandbox/router-example.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts...

我們的項目有兩個依賴項 - react-router-dom 對於路由器,axios 用於進行 API 調用。

npm install react-router-dom axios

yarn add react-router-dom axios

瀏覽器路由器

使用 react-router-dom ,我們需要包裝整個 App BrowserRouter 中的組件 .路由器有兩種類型:

  • BrowserRouter - 製作漂亮的 URL,例如 example.com/about .
  • HashRouter - 使用看起來像 example.com/#about 的 octothorpe(或標籤,如果你願意的話)製作 URL .

讓我們使用 BrowserRouter .

src/index.js
import React from 'react'
import { render } from 'react-dom'
import { BrowserRouter } from 'react-router-dom'
import App from './App'

render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.querySelector('#root')
)

路由和切換

現在在 App.js ,我們可以決定我們想要使用的路線並相應地指導。我們將使用 RouteSwitch 為了這個任務。

  • Switch - 將您的所有路線組合在一起,並確保它們從上到下優先。
  • Route - 每條路線。
App.js
import React from 'react'
import { Route, Switch } from 'react-router-dom'
// We will create these two pages in a moment
import HomePage from './pages/HomePage'
import UserPage from './pages/UserPage'

export default function App() {
  return (
    <Switch>
      <Route exact path="/" component={HomePage} />
      <Route path="/:id" component={UserPage} />
    </Switch>
  )
}

我們正在匹配根路由 (/ ) 到 HomePage , 並將任何其他頁面動態匹配到 UserPage .對於這個簡單的例子,我只有一條路線,但你可以做更多這樣的事情:

<Switch>
  <Route exact path="/" component={HomePage} />
  <Route path="/:id" component={UserPage} />
  <Route path="/categories" component={CategoriesPage} />
  <Route path="/categories/:id" component={IndividualCategoryPage} />
</Switch>

這將確保 taniarascia.com/categories 會轉到列出所有類別的頁面,但 taniarascia.com/categories/javascript 將轉到一個完全不同的模板,用於單個類別列表。

為了鏈接到 SPA 中的頁面,我們將使用 Link .如果我們使用傳統的 <a href="/route"> ,它會發出一個全新的請求並重新加載頁面,所以我們有 Link 來幫助我們。

src/pages/HomePage.js
import React from 'react'
import { Link } from 'react-router-dom'

export default function HomePage() {
  return (
    <div className="container">
      <h1>Home Page</h1>
      <p>
        <Link to="/taniarascia">taniarascia</Link> on GitHub.
      </p>
    </div>
  )
}

所以現在我要去我的第一條路線,正在加載 HomePage 的根路線 ,我看到了內容和鏈接。

動態路由參數

我們的 Link 正在導航到 /taniarascia , 這將匹配 /:id Route 中的參數 .為了從 URL 動態獲取內容 - 在本例中,taniarascia - 我們將使用 match.params.id 來自 props .

我將使用該參數調用 GitHub API 並檢索我的數據。在這個示例中,我將使用 Hooks,因此如果您不熟悉它們,請閱讀使用 Hooks 構建 CRUD 應用程序。

src/pages/UserPage.js
import React, { useState, useEffect } from 'react'
import axios from 'axios'

export default function UserPage(props) {
  // Setting initial state
  const initialUserState = {
    user: {},
    loading: true,
  }

  // Getter and setter for user state
  const [user, setUser] = useState(initialUserState)

  // Using useEffect to retrieve data from an API (similar to componentDidMount in a class)
  useEffect(() => {
    const getUser = async () => {
      // Pass our param (:id) to the API call
      const { data } = await axios(
        `https://api.github.com/users/${props.match.params.id}`
      )

      // Update state
      setUser(data)
    }

    // Invoke the async function
    getUser()
  }, []) // Don't forget the `[]`, which will prevent useEffect from running in an infinite loop

  // Return a table with some data from the API.
  return user.loading ? (
    <div>Loading...</div>
  ) : (
    <div className="container">
      <h1>{props.match.params.id}</h1>

      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Location</th>
            <th>Website</th>
            <th>Followers</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>{user.name}</td>
            <td>{user.location}</td>
            <td>
              <a href={user.blog}>{user.blog}</a>
            </td>
            <td>{user.followers}</td>
          </tr>
        </tbody>
      </table>
    </div>
  )
}

結論

如果你在途中迷路了,請在 GitHub 上查看源代碼。

  • 查看源代碼

此外,還有一個警告:如果你想在 GitHub Pages 上使用它,那麼意識到 you.github.io/repo/:id 是不夠聰明的 應該指向 /:id .如果您想在 GitHub 頁面上託管並遇到此問題,在 GitHub 頁面上託管您的單頁應用程序將幫助您。


Tutorial JavaScript 教程
  1. setTimeout 但在給定時間

  2. 我還沒準備好成為 Babel 的維護者

  3. 如何在 Ionic 和 VueJS 中使用 Storybook

  4. Web開發中的錯誤預防

  5. 使用 Yeoman 生成器搭建你的 GitHub 操作 🚀

  6. NodeJS 中的 MySQL 編輯器 ~ 第一部分

  7. 節點操作系統模塊

  1. wii 和 JavaScript

  2. NodeJS 18 獲取 API

  3. 使用 GitHub Actions 自動發佈到 npm?是的,請!

  4. 使用 Node、Express 和 Multer 的 React 單文件上傳教程

  5. 如何在 React 中處理表單,另一種方法

  6. 在 Red Hat Mobile Node.js 應用程序中使用 New Relic

  7. 使用 Javascript(並且沒有modernizr)檢測 CSS 轉換?

  1. 將 limit() 與 Mongoose 查詢一起使用

  2. 在本地設置 MongoDB(4.2.10) 和 MongoDB Compass

  3. 從現有 Git 存儲庫運行放大項目的 4 種方法。

  4. 每個開發人員都經歷過的地獄