加载器与操作(数据路由 API)
在渲染前通过加载器获取路由数据,并使用操作处理表单提交。
加载器与操作(数据路由 API) 是 CoddyKit 上的免费 React Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 React Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 React Academy 课程共包含 4 节课。
什么是加载器
在 React Router v6.4+ 数据路由中,加载器是路由上的异步函数,会在路由渲染之前获取数据,从而取代使用 useEffect 获取数据的模式。
定义加载器
向路由对象添加 loader 属性。它会接收 { params, request },并返回数据(或响应对象)。
import { createBrowserRouter } from 'react-router-dom';
async function userLoader({ params }) {
const res = await fetch(`/api/users/${params.id}`);
if (!res.ok) throw new Response('Not Found', { status: 404 });
return res.json();
}
const router = createBrowserRouter([
{ path: '/users/:id', element: <UserDetail />, loader: userLoader },
]);使用 useLoaderData 读取加载器数据
useLoaderData() 会返回加载器返回的内容。只有在加载器完成后,组件才会进行渲染。
import { useLoaderData } from 'react-router-dom';
function UserDetail() {
const user = useLoaderData();
return <h1>{user.name}</h1>;
}什么是操作函数
操作函数是用于处理数据变更的异步函数(例如表单提交和删除)。在表单 POST 之后、路由重新渲染之前,它会运行。
async function createUserAction({ request }) {
const formData = await request.formData();
const name = formData.get('name');
await fetch('/api/users', {
method: 'POST',
body: JSON.stringify({ name }),
headers: { 'Content-Type': 'application/json' },
});
return redirect('/users');
}使用 Form 触发操作函数
请将 <form> 替换为 React Router 的 <Form>。提交时,它会将字段序列化为 FormData,并调用路由的操作函数。
import { Form } from 'react-router-dom';
function NewUser() {
return (
<Form method="post">
<input name="name" />
<button type="submit">Create</button>
</Form>
);
}从操作函数返回数据
操作函数可以返回数据,而不仅仅是重定向。您可以在组件中使用 useActionData() 读取这些数据,这对于返回验证错误很有用。
async function loginAction({ request }) {
const data = await request.formData();
const errors = validate(data);
if (errors) return errors; // returned to useActionData
await login(data);
return redirect('/dashboard');
}
function Login() {
const errors = useActionData();
return (
<Form method="post">
{errors?.email && <p>{errors.email}</p>}
<input name="email" />
</Form>
);
}使用 useNavigation 处理加载状态
useNavigation() 会告诉您加载器或操作函数何时正在执行,以便您显示加载指示器或禁用提交按钮。
function SubmitButton() {
const navigation = useNavigation();
const isSubmitting = navigation.state === 'submitting';
return (
<button type="submit" disabled={isSubmitting}>
{isSubmitting ? 'Saving...' : 'Save'}
</button>
);
}使用 defer() 延迟数据
使用 defer() 从加载器返回不会阻塞渲染的慢速数据异步结果,然后使用 <Await> 和 Suspense 将其展开。
import { defer, Await } from 'react-router-dom';
async function slowLoader() {
return defer({ fast: await getFast(), slow: getSlow() });
}
function Page() {
const { fast, slow } = useLoaderData();
return (
<>
<h1>{fast.title}</h1>
<Suspense fallback={<p>Loading...</p>}>
<Await resolve={slow}>{data => <Chart data={data} />}</Await>
</Suspense>
</>
);
}操作函数后的重新验证
操作函数完成后,React Router 会自动重新运行所有活动的加载器以刷新数据,无需手动重新获取。
处理加载器中的错误
您可以从加载器中抛出 Response 或任意错误;React Router 会捕获该错误并渲染路由的 errorElement,您可以通过 useRouteError() 访问它。
function ErrorPage() {
const error = useRouteError();
return (
<div>
<h1>{error.status} {error.statusText}</h1>
</div>
);
}使用 Fetcher 处理非导航变更
useFetcher() 让您无需导航即可调用加载器或操作函数。这对于内联表单很有用,例如在不离开当前页面的情况下为帖子点赞。
function LikeButton({ postId }) {
const fetcher = useFetcher();
return (
<fetcher.Form method="post" action={`/posts/${postId}/like`}>
<button type="submit">Like</button>
</fetcher.Form>
);
}快速检查
哪个钩子可以读取路由加载器函数返回的数据?
回顾
React Router 的数据接口使用加载器在渲染前获取数据,使用操作函数处理数据变更。组件通过 useLoaderData() 读取加载器数据,通过 useActionData() 读取操作结果,并通过 useNavigation() 读取导航状态。
常见问题解答
「加载器与操作(数据路由 API)」课时是免费的吗?
是的 — 「加载器与操作(数据路由 API)」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 React Academy 课程的其余内容,请升级到 CoddyKit PRO。 React Academy 课程共包含 4 节课。
「加载器与操作(数据路由 API)」这节课中我会学到什么?
在渲染前通过加载器获取路由数据,并使用操作处理表单提交。 你通过在浏览器中直接运行的动手代码来练习 React Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 React Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 React Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「加载器与操作(数据路由 API)」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 React Academy 课中编写并运行代码吗?
能。每节 React Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 嵌套路由与 Outlet 布局
- 加载器与操作(数据路由 API)
- 受保护路由与身份验证守卫
- 管理 URL 搜索参数中的状态