Client Components使用async/await报错,寻求该场景解决方案
错误的核心是你把带有'use client'指令的Demo组件(Client Component)和包含async/await逻辑的Index1组件(Server Component)混用了——Client Component运行在浏览器端,不支持组件级的async/await,也不能直接引入并渲染Server Component。
下面是几种可行的解决方案:
方案一:移除Demo组件的'use client'指令
如果Demo组件不需要客户端交互逻辑(比如没有点击事件、状态管理等需求),直接去掉'use client',让它成为Server Component,这样就能正常引入并渲染async的Index1组件:
修改后的Demo组件代码:
import Index1 from "./index1"; const Demo = () => {return (<div><Index1 /></div>);}; export default Demo;
Index1组件保持原代码不变,它会在服务端完成数据获取和渲染,再把结果返回给客户端。
方案二:保留Demo为Client Component,调整数据获取逻辑
如果Demo必须是Client Component(比如需要实现客户端交互),可以通过以下两种方式调整:
方式1:将Index1改为客户端数据获取模式
给Index1加上'use client'指令,用React的useEffect钩子执行fetch操作,替换组件级的async/await:
"use client"; import { useEffect, useState } from "react"; export default function Index1() { const [repo, setRepo] = useState([]); useEffect(() => { const fetchUsers = async () => { const res = await fetch("https://jsonplaceholder.typicode.com/users"); const data = await res.json(); setRepo(data); }; fetchUsers(); }, []); return ( <div> {repo.map((user) => <div key={user.id}>{user.name}</div>)} </div> ); }
Demo组件保持原有代码不变,现在Index1也是Client Component,可正常被引入使用。
方式2:拆分数据逻辑到独立的Server Component
把数据获取的逻辑抽离成单独的Server Component,Demo作为Client Component只负责渲染这个子组件:
- 新建
UserList.server.jsx文件(后缀可帮助区分Server Component):
export default async function UserList() { const res = await fetch("https://jsonplaceholder.typicode.com/users"); const repo = await res.json(); return ( <div> {repo.map((user) => <div key={user.id}>{user.name}</div>)} </div> ); }
- 修改Demo组件:
"use client"; import UserList from "./UserList.server"; const Demo = () => {return (<div><UserList /></div>);}; export default Demo;
注意:Client Component可以将Server Component作为子组件渲染,但不能在自身的顶层代码中使用await调用Server Component,只能像普通组件一样引入渲染。
内容的提问来源于stack exchange,提问作者Rahul Chauhan

