在 React Router v6 中,loader
函数用于在导航到某个路由之前预加载数据。这是非常有用的功能,特别是在需要从服务器获取数据并将其传递给组件的情况下。loader
函数可以帮助你提前获取数据,从而提高用户体验和应用性能。
loader
函数的作用
-
数据预加载:
loader
函数在导航到指定路由之前被调用,用于获取必要的数据。- 这些数据可以是从服务器获取的 API 数据、本地存储的数据等。
-
异步数据加载:
loader
函数可以返回一个 Promise,通常用于处理异步操作,如 fetch 请求。- 如果
loader
函数返回一个 Promise,React Router 会等待 Promise 解析后再渲染对应的组件。
-
数据传递:
loader
函数返回的数据可以通过useLoaderData
钩子在组件中访问。- 这使得组件可以直接使用已经加载好的数据,而不需要再次发起请求。
示例
假设你有一个简单的应用,包含一个根路由和一个子路由,每个路由都有一个 loader
函数来加载数据。
定义 loader
函数
// rootLoader.js
export async function rootLoader() {
const response = await fetch('https://api.example.com/root-data');
if (!response.ok) {
throw new Error('Failed to fetch root data');
}
return response.json();
}
// teamLoader.js
export async function teamLoader() {
const response = await fetch('https://api.example.com/team-data');
if (!response.ok) {
throw new Error('Failed to fetch team data');
}
return response.json();
}
创建路由器
import { createBrowserRouter } from 'react-router-dom';
import Root from './components/Root';
import Team from './components/Team';
import { rootLoader } from './loaders/rootLoader';
import { teamLoader } from './loaders/teamLoader';
const router = createBrowserRouter([
{
path: '/',
element: <Root />,
loader: rootLoader,
children: [
{
path: 'team',
element: <Team />,
loader: teamLoader,
},
],
},
]);
export default router;
使用 useLoaderData 钩子
在组件中使用 useLoaderData 钩子来访问 loader 函数返回的数据。
// Root.js
import React from 'react';
import { useLoaderData } from 'react-router-dom';
const Root = () => {
const rootData = useLoaderData();
return (
<div>
<h1>Root Component</h1>
<pre>{JSON.stringify(rootData, null, 2)}</pre>
</div>
);
};
export default Root;
// Team.js
import React from 'react';
import { useLoaderData } from 'react-router-dom';
const Team = () => {
const teamData = useLoaderData();
return (
<div>
<h1>Team Component</h1>
<pre>{JSON.stringify(teamData, null, 2)}</pre>
</div>
);
};
export default Team;
loader
的作用和优点
-
数据预加载:在组件渲染之前加载数据,可以避免在组件内部使用
useEffect
等钩子来进行数据请求,从而提高性能。 -
简化组件逻辑:将数据请求逻辑从组件中抽离出来,使组件更专注于 UI 的渲染和交互逻辑。
-
支持异步数据加载:
loader
支持返回一个 Promise,这样可以在数据请求完成后再渲染组件。 -
错误处理:可以在
loader
中处理数据加载过程中的错误,比如返回一个错误页面或重定向到其他路径。