loader
每个路由都可以定义一个 loader
函数,在渲染之前向路由元素提供数据。
createBrowserRouter([
{
element: <Teams />,
path: "teams",
loader: async () => {
return fakeDb.from("teams").select("*");
},
children: [
{
element: <Team />,
path: ":teamId",
loader: async ({ params }) => {
return fetch(`/api/teams/${params.teamId}.json`);
},
},
],
},
]);
当用户在应用程序中导航时,将并行调用下一个匹配路线分支的加载器,并通过useLoaderData
将其数据提供给组件。
params
路由参数从动态段解析并传递给加载器。这对于确定加载哪个资源很有用:
createBrowserRouter([
{
path: "/teams/:teamId",
loader: ({ params }) => {
return fakeGetTeam(params.teamId);
},
},
]);
路径中的:teamId
被解析并作为同名的params.teamId
提供给 loader
。
request
这是向您的应用程序发出的 Fetch Request 实例。
function loader({ request }) {}
<a
href={props.to}
onClick={(event) => {
event.preventDefault();
navigate(props.to);
}}
/>
如果没有 React Router,浏览器会向您的服务器发出请求,但 React Router 阻止了它!React Router 将请求发送给加载器,而不是浏览器将请求发送到服务器。
最常见的用例是创建一个 URL 并从中读取 URLSearchParams:
function loader({ request }) {
const url = new URL(request.url);
const searchTerm = url.searchParams.get("q");
return searchProducts(searchTerm);
}
这里的 API 不是特定于 React Router 的,而是标准的web对象:Request
、URL
、URLSearchParams
。
loader.hydrate
如果你是服务器端渲染,并利用future.v7_partialHydration标志进行部分水合,那么你可能希望在初始水合时运行路由加载器,即使它有水合数据(例如,让用户用水合数据填充缓存)。要强制加载器在部分水合情况下运行水合,您可以在加载器功能上设置水合属性:
Returning Responses
你可以从 loader
返回任何你想要的东西,并从 useLoaderData
访问它,你也可以返回一个web
响应。
这可能看起来没有立竿见影的效果,但考虑一下 fetch
。由于 fetch
的返回值是 Response
,并且加载器理解响应,因此许多加载器可以返回简单的 fetch!
// an HTTP/REST API
function loader({ request }) {
return fetch("/api/teams.json", {
signal: request.signal,
});
}
// or even a graphql endpoint
function loader({ request, params }) {
return fetch("/_gql", {
signal: request.signal,
method: "post",
body: JSON.stringify({
query: gql`...`,
params: params,
}),
});
}
您也可以自己构建响应:
function loader({ request, params }) {
const data = { some: "thing" };
return new Response(JSON.stringify(data), {
status: 200,
headers: {
"Content-Type": "application/json; utf-8",
},
});
}
React Router 会自动调用response.json()
,这样你的组件在渲染时就不需要解析它了:
function SomeRoute() {
const data = useLoaderData();
}
使用 json 方法可以简化了这一过程,您不必自己构建 Response
:
import { json } from "react-router-dom";
function loader({ request, params }) {
const data = { some: "thing" };
return json(data, { status: 200 });
}
如果您计划升级到 Remix,则从每个加载器返回响应将使迁移更加顺利。
在 loader 中抛出异常
你可以在loader
中抛出异常,来跳出当前的调用堆栈(停止运行当前代码),React Router 将沿着错误路径重新启动。
function loader({ request, params }) {
const res = await fetch(`/api/properties/${params.id}`);
if (res.status === 404) {
throw new Response("Not Found", { status: 404 });
}
return res.json();
}
有关更多详细信息,请阅读 errorElement 文档。
最后更新于
这有帮助吗?