You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在服务器组件中用useState?解决Client Component async/await报错问题

React 组件常见问题解决方案

1. 服务器组件中怎么用 useState 这类钩子?

服务器组件(Server Components)不能直接用useState、useEffect这些客户端专属钩子——因为服务器组件运行在服务端,没有浏览器环境,也不维护客户端状态。

解决办法:

  • 拆分组件:把需要状态管理的部分单独做成标记'use client'的客户端组件,服务器组件用async/await获取数据,再把数据通过props传给客户端组件即可。
  • 框架适配:使用Next.js这类框架时,让服务器组件负责获取数据,客户端组件专门处理交互和状态逻辑,两者通过props传递数据。

2. 客户端组件混用 async/await 和 useState 报错的解决办法

报错Error: async/await is not yet supported in Client Components, only Server Components的问题出在:React目前不支持把客户端组件定义成async函数。

修复步骤:

  1. 移除组件的async关键字,将数据请求逻辑放到useEffect钩子内执行
  2. 初始化数据状态,在useEffect中完成fetch请求并更新状态
  3. 修正代码中的语法错误(如变量名错误、JSX标签未闭合、缺少useState导入)

修正后的完整代码:

'use client'
import { useState, useEffect } from 'react';

function Teachers (){
    const [showNames, setShowNames] = useState(false);
    const [data, setData] = useState([]);
    const [loading, setLoading] = useState(true);

    const teacherHandler = () => {
        setShowNames(!showNames);
    }

    useEffect(() => {
        const fetchTeachers = async () => {
            try {
                const response = await fetch('http://localhost:8000/teachers');
                const fetchedData = await response.json();
                setData(fetchedData);
            } catch (error) {
                console.error('获取教师数据失败:', error);
            } finally {
                setLoading(false);
            }
        };
        fetchTeachers();
    }, []);

    if (loading) {
        return <div className="text-center text-white mt-10">加载中...</div>;
    }

    return (
        <div className="mt-10">
            <div className="text-center font-DanaDemiBold text-3xl text-white">
                <h1 className="w-full bg-slate-900 mb-5">Teachers</h1>
                <button onClick={teacherHandler} className="p-3 bg-green-600 rounded-lg mt-5">Show/Hide Teachers Name</button>
            </div>
            <div className="flex justify-center items-center flex-wrap p-2 gap-3 my-10">
                {showNames ? data.map(item => (      
                    <div key={item.id} className="w-1/3 h-[300px] flex justify-between items-center shadow-lg bg-slate-300 rounded-lg">
                        <div className="flex flex-col m-10 gap-y-5">
                            <div className="flex gap-x-2">
                                <h3> Name: </h3>
                                <span>{item.firstname}</span>
                                <span>{item.lastname}</span>
                            </div>
                            <div className="flex gap-x-2">
                                <h3> Email: </h3>
                                <span>{item.email}</span>
                            </div>
                            <div className="flex gap-x-2">
                                <h3> Date of Birth: </h3>
                                <span>{item.birthDate}</span>
                            </div>
                            <div className="flex gap-x-2">
                                <h3> Phone: </h3>
                                <span>{item.mobile}</span>
                            </div>
                            <div className="flex gap-x-2">
                                <h3> Address: </h3>
                                <span>{item.address}</span>
                            </div>
                        </div>
                        <div className="w-36 h-36 m-10">
                            <img className="rounded-full" src={item.profileImg} alt="profile"/>
                        </div>
                    </div>
                )) : null}
            </div>
        </div>
    )
}

export default Teachers;

关键修复点:

  • 补充了useState和useEffect的导入语句
  • 用useEffect包裹异步请求逻辑,避免将组件定义为async函数
  • 添加loading状态,优化加载阶段的用户体验
  • 修正变量名错误(将showTeachers改为showNames)
  • 修复JSX标签闭合问题(原代码中button后多余的分号、未闭合的div标签)

内容的提问来源于stack exchange,提问作者Mehrdad Kohanpur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 14:42:04