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

React useRef/useEffect 阻止effect首次渲染执行的实现问题

问题原因

你的核心实现思路在非严格模式的生产环境下可以正常运行,开发环境出现首次挂载就执行的问题,是React 18+ 严格模式(Strict Mode)的特殊机制导致的:

  • 开发环境开启严格模式时,组件首次挂载阶段React会主动执行两轮副作用流程:挂载执行effect → 执行effect清理 → 重新挂载执行effect,目的是提前暴露缺失清理逻辑的副作用bug
  • 你的原代码没有编写effect清理逻辑,第一轮effect执行时会把isMounted.current设为true,第二轮模拟重挂载执行effect时,ref保存的标记已经是true,就会直接触发fetchData(),表现为首次挂载就执行了逻辑。

本质上用isMounted标记跳过首次渲染的方案,是绕开了「useEffect默认首次执行」的默认行为,并没有直接贴合你的核心需求:仅在success值发生变化时执行逻辑,这类标记方案很容易受React生命周期执行规则变化的影响。

可靠实现方案

直接通过ref记录上一次的success值,每次effect执行时对比前后值,只有值确实发生变化时才执行业务逻辑,完全绕开挂载次数、严格模式的影响,完全匹配需求:

// 初始化时存储success的初始值
const prevSuccess = useRef(success);

useEffect(() => {
  // 当前值和上一次记录的值不一致,说明是success变化触发的执行
  if (prevSuccess.current !== success) {
    fetchData();
    // 执行完成后更新ref存储的旧值
    prevSuccess.current = success;
  }
}, [success]);

这个实现的表现完全符合预期:

  • 首次挂载时,ref存储的值和当前success值完全相等,不会执行fetchData
  • 后续每次success更新,前后值不相等时才会触发业务逻辑
  • 不受严格模式双调用、React版本生命周期规则调整的影响

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 15:24:25