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

React useEffect依赖无变化仍触发?求原因及最佳实践

问题原因

React 中 useEffect 的设计逻辑是:组件首次挂载时一定会执行一次回调,依赖数组的作用仅用于控制组件后续重新渲染时,是否触发回调。哪怕依赖数组里的状态从未被修改,首次挂载的执行也是默认行为,这是为了支持初始化时的副作用操作(比如请求数据、绑定事件)。

优雅解决方案与最佳实践

方案1:用Ref标记首次挂载

通过 useRef 创建一个标记变量,记录是否是组件首次渲染,在 useEffect 中跳过首次执行的逻辑:

import React from 'react';

export function App(props) {
  const [testString, setTestString] = React.useState('abc');
  // 标记是否为首次挂载
  const isFirstMount = React.useRef(true);

  React.useEffect(() => {
    if (isFirstMount.current) {
      // 首次挂载时更新标记,不执行业务逻辑
      isFirstMount.current = false;
      return;
    }
    // 仅当testString变化时才执行的逻辑
    console.log('******* 只有state变化时才会触发!')
  }, [testString]);

  return (
    <div className='App'>
      <h1>Hello React.</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

方案2:封装自定义Hook(最佳实践)

如果多个组件都需要这个逻辑,可以把判断首次挂载的逻辑封装成可复用的自定义Hook,提高代码复用性:

import React from 'react';

// 自定义Hook:仅在依赖变化时执行,跳过首次挂载
function useUpdateEffect(effect, dependencies) {
  const isFirstMount = React.useRef(true);

  React.useEffect(() => {
    if (isFirstMount.current) {
      isFirstMount.current = false;
    } else {
      return effect();
    }
  }, dependencies);
}

export function App(props) {
  const [testString, setTestString] = React.useState('abc');

  // 使用自定义Hook
  useUpdateEffect(() => {
    console.log('******* 只有state变化时才会触发!')
  }, [testString]);

  return (
    <div className='App'>
      <h1>Hello React.</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 05:52:43