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

如何使用useEffect设置状态并避免无限重渲染(医生评分场景)

解决无限重渲染并实现需求的方案

1. 修复useEffect的依赖与执行逻辑

无限重渲染的核心原因是useEffect依赖了doctor状态:初始doctor为null时触发请求,请求完成后setDoctor(data)更新状态,组件重渲染,useEffect因doctor引用变化再次执行;后续用户评分后setDoctor(null),又会循环触发请求→更新状态→重渲染的流程,形成无限循环。

将useEffect的依赖改为医生id,并调整加载逻辑,确保页面刷新或医生ID变化时自动获取数据:

useEffect(() => {
    axios.get(`doctor/${id}`).then(({data}) => {
        setDoctor(data)
    })
}, [id])

2. 优化评分后的医生数据更新逻辑

无需通过setDoctor(null)触发重新加载,直接在评分请求成功后获取最新的医生数据,确保平均评分实时更新:

const handleReview = async () => {
    try {
        if(text === '' || rating === 0){
            errorNotification('field cannot be empty')
        }else {
            await axios.post(`/doctor/${id}/review`, {
                text, 
                rating, 
                createdAt: moment(dayjs(date).toDate()).format('LL') 
            })
            // 评分成功后重新获取最新的医生数据,更新状态
            const {data} = await axios.get(`doctor/${id}`)
            setDoctor(data)
            
            setText('')
            setRating(0)
            setGiveReview(false)
            successfulNotification('feedback received')
        }
    } catch (error) {
        errorNotification('error, please try again later')
    }
}

如果后端在评分接口返回更新后的医生信息,也可以直接用返回值更新doctor状态,省去一次GET请求:

// 替换上面的GET请求逻辑
const response = await axios.post(`/doctor/${id}/review`, {/* 请求参数 */})
setDoctor(response.data.updatedDoctor)

3. 可选优化:防止重复请求

若存在医生ID频繁变化的场景,可添加加载状态避免重复请求:

const [isLoading, setIsLoading] = useState(false)

useEffect(() => {
    const fetchDoctor = async () => {
        if(isLoading) return
        setIsLoading(true)
        try {
            const {data} = await axios.get(`doctor/${id}`)
            setDoctor(data)
        } finally {
            setIsLoading(false)
        }
    }
    fetchDoctor()
}, [id])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 05:40:17