偶然看到 React Router 6.4 版本的更新,其中最重磅的就是多了一系列 Data**Router,以及附带的 loaders, actions, fetchers 等 API。
Intro
一个来自官方的示例:
<DataBrowserRouter>
<Route
element={<Teams />}
path="teams"
loader={async () => {
return fakeDb.from("teams").select("*");
}}
>
<Route
element={<Team />}
path=":teamId"
loader={async ({ params }) => {
return fetch(`/api/teams/${params.teamId}.json`);
}}
/>
</Route>
<Route
path="project/new"
action={async ({ request }) => {
const formData = await request.formData();
const newProject = await createProject({
title: formData.get("title"),
due: formData.get("due"),
});
return redirect(`/projects/${newProject.id}`);
}}
/>
</DataBrowserRouter>
看到 loader 和 action 的用法是不是有点熟悉?
没错,就是来自于 remix,下面再来一段 Remix 官网的代码截图,是不是有亿点点类似呢?
意图表露的已经很明显了,React Router 团队准备做一个基于 Remix 内核的平台。
Migrate
图中为一个简单的列表页面,useEffect 触发时获取数据,算是比较典型的模型。
安装最新版 react-router-dom
npm i react-router-dom@6.4.0-pre.14
BrowserRouter 替换为 DataBrowserRouter,并移除 Routes 组件
<DataBrowserRouter>
<Route path='/' element={<BasicLayout />}>
{renderRoute(routes)}
</Route>
</DataBrowserRouter>
在组件中编写 loader 回调函数
export function loader () {
const data = [
{
id: 1,
name: 'Project 1'
},
{
id: 2,
name: 'Project 2'
}
]
return data
}
使用 loader 回调,这里没有像 Remix 或者 Next.js 一样自动调用,而是要手动配置,并且如果路由组件是懒加载时就会比较尴尬,因为 loader 就要另外导入了。
import { loader as ProjectLoader } from './pages/project'
{
path: '/project',
component: lazy(() => import('./pages/project')),
loader: ProjectLoader,
},
刷新页面,成功从 loader 拿到数据。
其他还新增了很多东西,就不做赘述了,因为改动较大,有时间的可以研究研究,尤其是想要玩一玩 SSR 的。