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

React Hooks useEffect依赖data引发无限循环问题求解

解决React useEffect依赖冲突:避免无限循环同时满足ESLint规则

咱们先拆解下你的问题:你想在useEffect里根据data的状态执行逻辑,但把data加入依赖列表会触发无限循环(因为每次setData都会更新data,进而重新执行useEffect),而直接忽略ESLint提示又不太规范。下面给你两个可行的方案,优先推荐第一种优雅的解法:

方案1:使用useRef保存data的最新状态

useRef的特性是它的.current属性可以保存可变值,而且更新它不会触发组件重渲染,也不会影响useEffect的依赖检测。我们可以用它同步data的最新值,这样在useEffect里就能访问到最新的data,同时不用把data加入依赖列表。

修改后的代码如下:

import React, { useState, useEffect, useRef } from "react";

const App = () => {
  const [data, setData] = useState<null | any[]>(null);
  const [checked, setChecked] = useState(false);
  const [loading, setLoading] = useState(false);
  // 创建ref同步data的最新值
  const dataRef = useRef(data);

  // 监听data变化,同步更新ref
  useEffect(() => {
    dataRef.current = data;
  }, [data]);

  useEffect(() => {
    setLoading(true);
    (async () => {
      // 这里访问dataRef.current代替原有的data
      if (dataRef.current) {
        console.log("Data exists already");
        // 执行你需要的异步操作
      }
      const ret = await fetch("https://jsonplaceholder.typicode.com/users?delay=1000", { cache: "no-store" });
      const json = await ret.json();
      setData(json);
      setLoading(false);
    })();
  }, [checked]); // 依赖列表只保留checked,不会触发无限循环

  return (
    <>
      <h1>useEffect Testing {loading && " ⌛"}</h1>
      <hr />
      <input type="checkbox" checked={checked} onChange={(e) => setChecked(e.target.checked)} />
      <pre style={{ fontSize: "0.8em" }}>{JSON.stringify(data)}</pre>
    </>
  );
};

export default App;

为什么这个方案有效?

  • dataRef会始终同步data的最新状态,但它的更新不会触发组件重渲染,也不会让useEffect重新执行。
  • 原useEffect的依赖只有checked,只有当复选框状态变化时才会触发,避免了无限循环。
  • ESLint的react-hooks/exhaustive-deps规则不会再报错,因为我们没有在useEffect里直接引用data,而是通过dataRef.current访问。

方案2:临时忽略ESLint提示(不推荐)

如果你确定当前场景下不需要把data加入依赖,可以用ESLint的注释临时忽略提示,但这是一种妥协方案,可能会掩盖未来的依赖问题,所以优先推荐方案1。

修改方式如下:

useEffect(() => {
  setLoading(true);
  (async () => {
    if (data) {
      console.log("Data exists already");
    }
    const ret = await fetch("https://jsonplaceholder.typicode.com/users?delay=1000", { cache: "no-store" });
    const json = await ret.json();
    setData(json);
    setLoading(false);
  })();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [checked]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 16:37:53