從組件路由採用框架
本頁面內容

從組件路由採用框架

如果您使用 <RouterProvider>,請參閱從 RouterProvider 採用框架

如果您使用 <Routes>,這裡是正確的地方。

React Router Vite 插件為 React Router 新增了框架功能。本指南將協助您在應用程式中採用此插件。如果您遇到任何問題,請在 TwitterDiscord 上尋求協助。

功能

Vite 插件新增了

  • 路由載入器、動作和自動資料重新驗證
  • 類型安全的路由模組
  • 自動路由程式碼分割
  • 跨導航的自動捲動位置恢復
  • 可選的靜態預先渲染
  • 可選的伺服器渲染

初始設定需要最多的工作。但是,一旦完成,您可以逐步採用新功能,一次一個路由。

先決條件

若要使用 Vite 插件,您的專案需要

  • Node.js 20+ (如果使用 Node 作為您的執行階段)
  • Vite 5+

1. 安裝 Vite 插件

👉 安裝 React Router Vite 插件

npm install -D @react-router/dev

👉 安裝執行階段轉接器

我們假設您使用 Node 作為您的執行階段。

npm install @react-router/node

👉 將 React 插件換成 React Router。

-import react from '@vitejs/plugin-react'
+import { reactRouter } from "@react-router/dev/vite";
import { defineConfig } from "vite";


export default defineConfig({
  plugins: [
-    react()
+    reactRouter()
  ],
});

2. 新增 React Router 配置

👉 建立 react-router.config.ts 檔案

將以下內容新增至專案的根目錄。在此配置中,您可以告訴 React Router 關於您的專案,例如在哪裡可以找到應用程式目錄,以及暫時不使用 SSR (伺服器端渲染)。

touch react-router.config.ts
import type { Config } from "@react-router/dev/config";

export default {
  appDirectory: "src",
  ssr: false,
} satisfies Config;

3. 新增根進入點

在典型的 Vite 應用程式中,index.html 檔案是捆綁的進入點。React Router Vite 插件將進入點移動到 root.tsx 檔案,以便您可以使用 React 渲染應用程式的外殼,而不是靜態 HTML,並且如果需要,最終可以升級到伺服器渲染。

👉 將您現有的 index.html 移動到 root.tsx

例如,如果您目前的 index.html 如下所示

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0"
    />
    <title>My App</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>

您會將該標記移動到 src/root.tsx 並刪除 index.html

touch src/root.tsx
import {
  Links,
  Meta,
  Outlet,
  Scripts,
  ScrollRestoration,
} from "react-router";

export function Layout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <head>
        <meta charSet="UTF-8" />
        <meta
          name="viewport"
          content="width=device-width, initial-scale=1.0"
        />
        <title>My App</title>
        <Meta />
        <Links />
      </head>
      <body>
        {children}
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  );
}

export default function Root() {
  return <Outlet />;
}

4. 新增客戶端進入模組

在典型的 Vite 應用程式中,index.html 檔案指向 src/main.tsx 作為客戶端進入點。React Router 使用名為 src/entry.client.tsx 的檔案來代替。

👉 將 src/entry.client.tsx 作為您的進入點

如果您目前的 src/main.tsx 如下所示

import React from "react";
import ReactDOM from "react-dom/client";
import { BrowserRouter } from "react-router";
import "./index.css";
import App from "./App";

ReactDOM.createRoot(
  document.getElementById("root")!
).render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

您會將其重新命名為 entry.client.tsx 並將其變更為如下所示

import React from "react";
import ReactDOM from "react-dom/client";
import { HydratedRouter } from "react-router/dom";
import "./index.css";

ReactDOM.hydrateRoot(
  document,
  <React.StrictMode>
    <HydratedRouter />
  </React.StrictMode>
);
  • 使用 hydrateRoot 而不是 createRoot
  • 渲染 <HydratedRouter> 而不是您的 <App/> 組件
  • 注意:我們停止渲染 <App/> 組件。我們將在稍後的步驟中將其帶回,但首先我們要讓應用程式使用新的進入點啟動。

5. 調整內容

root.tsxentry.client.tsx 之間,您可能想要在它們之間調整一些內容。

一般來說

  • root.tsx 包含任何渲染相關的東西,例如 context providers、版面配置、樣式等等。
  • entry.client.tsx 應盡可能簡潔
  • 請記住不要嘗試渲染您現有的 <App/> 組件,我們將在稍後的步驟中執行此操作

請注意,您的 root.tsx 檔案將會靜態產生並作為您應用程式的進入點提供,因此只有該模組需要與伺服器渲染相容。這將是您大部分麻煩的來源。

6. 設定您的路由

React Router Vite 插件使用 routes.ts 檔案來配置您的路由。目前,我們將新增一個簡單的 catchall 路由來開始。

👉 設定 catchall.tsx 路由

touch src/routes.ts src/catchall.tsx
import {
  type RouteConfig,
  route,
} from "@react-router/dev/routes";

export default [
  // * matches all URLs, the ? makes it optional so it will match / as well
  route("*?", "catchall.tsx"),
] satisfies RouteConfig;

👉 渲染預留位置路由

最終我們將用我們原始的 App 組件取代它,但目前我們只會渲染一些簡單的東西來確保我們可以啟動應用程式。

export default function Component() {
  return <div>Hello, world!</div>;
}

檢視我們的配置路由指南以深入瞭解 routes.ts 檔案。

7. 啟動應用程式

此時,您應該能夠啟動應用程式並看到根版面配置。

👉 新增 dev 指令碼並執行應用程式

"scripts": {
  "dev": "react-router dev"
}

現在,在繼續之前,請確保您可以在此時啟動您的應用程式

npm run dev

您可能想要將 .react-router/ 新增至您的 .gitignore 檔案,以避免在您的儲存庫中追蹤不必要的檔案。

.react-router/

您可以查看類型安全,以瞭解如何完整設定和使用自動產生的類型安全,以用於參數、載入器資料等等。

8. 渲染您的應用程式

若要返回渲染您的應用程式,我們將更新我們稍早設定的「catchall」路由,該路由符合所有 URL,以便您現有的 <Routes> 有機會渲染。

👉 更新 catchall 路由以渲染您的應用程式

import App from "./App";

export default function Component() {
  return <App />;
}

您的應用程式應該回到螢幕上並像往常一樣運作!

9. 將路由遷移至路由模組

您現在可以逐步將您的路由遷移至路由模組。

假設有像這樣的現有路由

// ...
import About from "./containers/About";

export default function App() {
  return (
    <Routes>
      <Route path="/about" element={<About />} />
    </Routes>
  );
}

👉 將路由定義新增至 routes.ts

import {
  type RouteConfig,
  route,
} from "@react-router/dev/routes";

export default [
  route("/about", "./pages/about.tsx"),
  route("*?", "catchall.tsx"),
] satisfies RouteConfig;

👉 新增路由模組

編輯路由模組以使用路由模組 API

export async function clientLoader() {
  // you can now fetch data here
  return {
    title: "About page",
  };
}

export default function Component({ loaderData }) {
  return <h1>{loaderData.title}</h1>;
}

請參閱類型安全,以設定自動產生的類型安全,以用於參數、載入器資料等等。

您遷移的前幾個路由是最困難的,因為您通常必須以與之前稍微不同的方式存取各種抽象 (例如在載入器中而不是從 Hook 或 Context)。但是,一旦處理完最棘手的部分,您就會進入逐步完善的節奏。

啟用 SSR 和/或預先渲染

如果您想要啟用伺服器渲染和靜態預先渲染,您可以使用捆綁器插件中的 ssrprerender 選項來執行此操作。對於 SSR,您還需要將伺服器組建部署到伺服器。請參閱部署以取得更多資訊。

import type { Config } from "@react-router/dev/config";

export default {
  ssr: true,
  async prerender() {
    return ["/", "/about", "/contact"];
  },
} satisfies Config;
文件與範例 CC 4.0