Menu
CoddyTech

异步组件

本课属于 Coddy React 学习旅程的“Next.js 基础”单元。第 23 课,共 47 课。

这是上一章所做准备带来的成果。服务器组件可以是 async:

import { getDishes } from '../lib/data';

export default async function Page() {
    const dishes = await getDishes();

    return <h1>{dishes.length} dishes</h1>;
}

再读一遍,因为这确实是个新概念。这个组件会等待。Next.js 会在服务器上运行它,让 await 执行完毕,然后才把结果转换成 HTML。

把它和你原本会编写的纯浏览器版本比较一下:

  • 页面最初会呈现为空白
  • 页面加载之后才会发出请求
  • 某些状态发生变化,内容随之出现,用户每次都会看到闪烁

使用异步服务器组件时,不会先渲染空内容。没有内容会闪烁着出现,因为构建 HTML 时数据已经就绪。不需要 useEffect,不需要加载标记,也不需要第二次请求。

有两条规则可以让这种写法合法:

  • 只有服务器组件可以使用 async:标记为 'use client' 的组件不可以
  • 数据必须来自服务器能够访问的地方:数据库、文件,或像 lib/data.js 这样的模块
challenge icon

挑战

简单

lib/data.js 已提供并锁定。它会导出 getDishes(),该函数会返回一个 Promise,其中包含由 { id, name } 对象组成的数组。

  1. 将 app/page.jsx 中的 Page 改为 async 函数。
  2. 使用 await getDishes(),并将结果存入 dishes 变量。
  3. 在 <ul id="dish-list"> 内,为每道菜渲染一个 <li>,并设置 key={dish.id}、id={dish.id},再将这道菜的 name 作为文本内容。

不要使用 useEffect,不要设置加载标记,只需使用 await。

亲手试试

import './globals.css';

export const metadata = {
    title: 'My App',
};

export default function RootLayout({ children }) {
    return (
        <html lang="en">
            <body>
                {children}
            </body>
        </html>
    );
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

Next.js 基础中的所有课