Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

静态路由数据 (Static Route Data)

在创建路由时,你可以选择在路由选项中指定一个 staticData 属性。只要该对象在创建路由时是同步可用的,它几乎可以包含任何你想要的内容。

除了可以从路由本身访问这些数据外,你还可以通过任何路由匹配项(match)的 match.staticData 属性来访问它。

示例

import { createFileRoute } from "@tanstack/react-router";

export const Route = createFileRoute("/posts")({
  staticData: {
    customData: "你好!",
  },
});

之后,你可以在任何能访问到路由的地方使用这些数据,包括可以映射回其路由的匹配项(matches)。

import { createRootRoute } from "@tanstack/react-router";

export const Route = createRootRoute({
  component: () => {
    const matches = useMatches();

    return (
      <div>
        {matches.map((match) => {
          return <div key={match.id}>{match.staticData.customData}</div>;
        })}
      </div>
    );
  },
});

强制执行静态数据类型

如果你想强制要求路由必须包含某些静态数据,可以使用“声明合并(Declaration Merging)”来为路由的静态选项添加类型定义:

declare module "@tanstack/react-router" {
  interface StaticDataRouteOption {
    customData: string;
  }
}

现在,如果你尝试创建一个没有 customData 属性的路由,将会收到类型错误:

export const Route = createFileRoute("/posts")({
  staticData: {
    // 错误:类型 '{ ... }' 中缺少属性 'customData',但类型 'StaticDataRouteOption' 中需要该属性。ts(2741)
  },
});

可选的静态数据

如果你希望静态数据是可选的,只需在属性后面加上 ?

declare module "@tanstack/react-router" {
  interface StaticDataRouteOption {
    customData?: string;
  }
}

只要 StaticDataRouteOption 中存在任何必选属性,你就必须传入一个对象。

常见模式

控制布局可见性

使用 staticData 来控制哪些路由显示或隐藏特定的布局元素:

export const Route = createFileRoute("/admin")({
  staticData: { showNavbar: false },
  component: AdminLayout,
});
// routes/__root.tsx
function RootComponent() {
  const showNavbar = useMatches({
    select: (matches) =>
      // 如果没有任何一个匹配的路由明确设置 showNavbar 为 false,则显示导航栏
      !matches.some((m) => m.staticData?.showNavbar === false),
  });

  return showNavbar ? (
    <Navbar>
      <Outlet />
    </Navbar>
  ) : (
    <Outlet />
  );
}

用于面包屑的路由标题

export const Route = createFileRoute("/posts/$postId")({
  staticData: {
    getTitle: () => "文章详情",
  },
});
function Breadcrumbs() {
  const matches = useMatches();

  return (
    <nav>
      {matches
        .filter((m) => m.staticData?.getTitle)
        .map((m) => (
          <span key={m.id}>{m.staticData.getTitle()}</span>
        ))}
    </nav>
  );
}

什么时候使用 staticData 而不是 Context?

特性staticDatacontext
时机同步,在路由创建时定义可以是异步的(通过 beforeLoad
可用性在加载开始前即可用可以依赖于 params/search 参数
共享性对于同一路由的所有实例都相同沿着路由树向下传递给子路由

总结: 对于静态的路由元数据(Metadata),请使用 staticData。对于动态数据或随请求变化的身份验证状态(Auth State),请使用 context