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
相关产品推荐
相关产品推荐

