rerumaccusamus
Version:
The meta-framework suite designed from scratch for frontend-focused modern web development.
62 lines (41 loc) • 2.64 kB
Markdown
title: 使用 Loader
到目前为止,我们都是用 `useEffect` 来请求 BFF,加载联系人列表数据。
在启用 SSR 的情况下,`useEffect` 在服务器端是不会执行的,所以 SSR 过程中不会加载数据,这种 SSR 只能渲染很有限的 UI,是低价值的。
可以在当前项目中开启 [SSR](docs/apis/config/server/ssr),看下这种效果。
```json
"server": {
"ssr": true,
}
```
执行 `pnpm run dev`,在 devtools 的 network 面板里查看 HTML 请求的 Preview 面板,可以看到 SSR 的渲染结果只有导航栏和 Pending... 字符,并没有联系人数据:

前面提到过,MWA 项目里的 SSR 实现是 Serverless SSR,不仅在部署、运维环节,在开发环节对 Server 也是无感的,项目里不需要专门写服务器的实现。
上述加载初始数据的业务逻辑,也不应该像传统模式一样,在客户端代码和服务器端代码中分别实现。
Modern.js 提供一个叫 `useLoader` 的 hooks API,在这种场景下替代 `useEffect`,能自动在 SSR 环节做**预加载**,先获取足够的数据,再运行 app 代码渲染 HTML。
同时,在 CSR 环节中,自动检查当前 loader 需要的数据,如果在 SSR 环节中已经预加载,在客户端就不再重复执行 loader,直接用现成数据;反之就在客户端执行 loader(相当于一种 fallback)。
`useLoader` 的使用很简单,把当前项目中 `Contacts` 组件中的 `useEffect` 代码替换成:
```js
useLoader(
async () => {
if (!items.length && !error && !pending) {
return actions.load();
}
return Promise.resolve();
},
{
params: 'contacts',
},
);
```
`useLoader` API 要求返回一个 promise,用于判断这个 loader 是否完成。第二个参数是当前 Loader 的唯一标识。
同时,在文件顶部的导入 `useLoader`:
```js
import { useLoader } from '@modern-js/runtime';
```
重新执行 `pnpm run dev`,查看 `view-source:http://localhost:8080/contacts/`,或在 devtools 的 Network 面板里查看 HTML 请求的「 Preview 」,可以看到 SSR 渲染出来的 HTML 已经包含完整的 UI:

查看 `http://localhost:8080/contacts/`,可以看到首屏是没有 pending 过程的。
> 本小节的代码可以在[这里查看](https://github.com/modern-js-dev/modern-js-examples/tree/main/tutorials/c11/hello-modern-3)。