React Router框架介绍

276 阅读2分钟

React Router

React Router 可最大限度地用作你的 React 框架。在这种配置下,你将使用 React Router 命令行界面(CLI)以及 Vite 打包工具插件来搭建全栈开发与部署架构。这使得 React Router 能够提供大多数 Web 项目所需的大量功能,包括:

  1. Vite 打包工具与开发服务器集成
  2. 热模块替换
  3. 代码拆分
  4. 具备类型安全的路由约定
  5. 基于文件系统或配置的路由
  6. 具备类型安全的数据加载
  7. 具备类型安全的操作
  8. 操作后页面数据的自动重新验证
  9. 服务端渲染(SSR)、单页应用(SPA)以及静态渲染策略
  10. 用于挂起状态和乐观用户界面(UI)的应用程序接口(API)
  11. 部署适配器

路由通过 “routes.ts” 文件进行配置,这使得 React Router 能够为你完成诸多事项。例如,它会自动对每条路由进行代码拆分,为参数和数据提供类型安全保障,并且在用户导航至相应路由时,能自动加载数据并可访问挂起状态。

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

export default [
  index("./home.tsx"),
  route("about", "./about.tsx"),

  layout("./auth/layout.tsx", [
    route("login", "./auth/login.tsx"),
    route("register", "./auth/register.tsx"),
  ]),

  ...prefix("concerts", [
    index("./concerts/home.tsx"),
    route(":city", "./concerts/city.tsx"),
    route(":city/:id", "./concerts/show.tsx")
    route("trending", "./concerts/trending.tsx"),
  ]),
] satisfies RouteConfig;

你将能够使用路由模块应用程序接口(API),其他大多数功能都是基于此构建的。加载器为路由组件提供数据:

// loaders provide data to components
export async function loader({ params }: Route.LoaderArgs) {
  const [show, isLiked] = await Promise.all([
    fakeDb.find("show", params.id),
    fakeIsLiked(params.city),
  ]);
  return { show, isLiked };
}

组件会依据在 “routes.ts” 文件中配置好的 URL 进行渲染,并将加载器提供的数据作为属性传入。

export default function Show({
  loaderData,
}: Route.ComponentProps) {
  const { show, isLiked } = loaderData;
  return (
    <div>
      <h1>{show.name}</h1>
      <p>{show.description}</p>

      <form method="post">
        <button
          type="submit"
          name="liked"
          value={isLiked ? 0 : 1}
        >
          {isLiked ? "Remove" : "Save"}
        </button>
      </form>
    </div>
  );
}

操作可以更新数据,并触发对页面上所有数据的重新验证,这样你的用户界面就能自动保持最新状态。

export async function action({
  request,
  params,
}: Route.LoaderArgs) {
  const formData = await request.formData();
  await fakeSetLikedShow(formData.get("liked"));
  return { ok: true };
}