使用React 16.8.6(在之前的版本16.8.3上很好),当我试图阻止fetch请求上的无限循环时,我得到了这个错误:
./src/components/BusinessesList.js
Line 51: React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array react-hooks/exhaustive-deps
我一直无法找到一个解决办法来停止这个无限循环。我想远离使用useReducer()。我确实找到了关于'筋疲力尽-deps' lint规则#14920的讨论[ESLint]反馈,其中一个可能的解决方案是,如果你认为你知道你在做什么,你可以总是// ESLint - disabled -next-line react-hooks/详尽-deps。我对我正在做的事情没有信心,所以我还没有尝试实现它。
我有这个当前的设置,React钩子useEffect连续运行永远/无限循环,唯一的评论是关于useCallback(),我不熟悉。
我目前如何使用useEffect()(我只想在开始时运行一次,类似componentDidMount()):
useEffect(() => {
fetchBusinesses();
}, []);
const fetchBusinesses = () => {
return fetch("theURL", {method: "GET"}
)
.then(res => normalizeResponseErrors(res))
.then(res => {
return res.json();
})
.then(rcvdBusinesses => {
// some stuff
})
.catch(err => {
// some error handling
});
};
你可以通过传递一个引用来消除这个Es-lint警告:
下面提到的例子,但是你可以在这个链接上观看解决方案:https://www.youtube.com/watch?v=r4A46oBIwZk&t=8s
警告:
第13:8行:反应。useEffect缺少依赖项:'history'和'currentUser?.role'。要么包含它们,要么删除依赖数组react-hooks/ exhaustion -deps
React.useEffect(() => {
if (currentUser?.role !== "Student") {
return history.push("/")
}
}, [])
解决方法:
步骤1:将业务逻辑移到单独的const中。
现在的警告是:React Hook React。useEffect有一个缺失的依赖:' rolecheck '。
const roleChecking = () =>{
if (currentUser?.role !== "Student") {
return history.push("/")
}
}
React.useEffect(() => {
roleChecking()
}, [])
最后一步是创建对函数的引用:
const roleRef = React.useRef();
const roleChecking = () => {
if (currentUser?.role !== "Student") {
return history.push("/");
}
};
roleRef.current = roleChecking;
React.useEffect(() => {
return roleRef.current();
}, [currentUser?.role]);
下一行禁用ESLint即可;
useEffect(() => {
fetchBusinesses();
// eslint-disable-next-line
}, []);
通过这种方式,您使用它就像使用组件挂载(调用一次)一样。
更新
or
const fetchBusinesses = useCallback(() => {
// Your logic in here
}, [someDeps])
useEffect(() => {
fetchBusinesses();
// No need to skip the ESLint warning
}, [fetchBusinesses]);
fetchBusinesses将在每次someDeps更改时被调用。
好吧,如果你想从不同的角度来看这个问题,你只需要知道React有哪些非耗尽的选项。你不应该在效果中使用闭包函数的原因之一是在每次渲染时,它都会被重新创建/销毁。
因此,钩子中有多个React方法被认为是稳定的和非耗尽的,在这些方法中,您不必应用到useEffect依赖项,并且反过来也不会破坏React -hooks/竭-deps的约定规则。例如,useReducer或useState的第二个返回变量是一个函数。
const [,dispatch] = useReducer(reducer, {});
useEffect(() => {
dispatch(); // Non-exhausted - ESLint won't nag about this
}, []);
所以反过来,你可以让所有的外部依赖关系与你在reducer函数中的当前依赖关系共存。
const [,dispatch] = useReducer((current, update) => {
const { foobar } = update;
// Logic
return { ...current, ...update };
}), {});
const [foobar, setFoobar] = useState(false);
useEffect(() => {
dispatch({ foobar }); // non-exhausted `dispatch` function
}, [foobar]);
./src/components/BusinessesList.js
Line 51: React Hook useEffect has a missing dependency: 'fetchBusinesses'.
Either include it or remove the dependency array react-hooks/exhaustive-deps
这不是一个JavaScript/React错误,而是一个ESLint (ESLint -plugin- React -hooks)警告。
它告诉你这个钩子依赖于fetchBusinesses函数,所以你应该把它作为一个依赖项传递。
useEffect(() => {
fetchBusinesses();
}, [fetchBusinesses]);
如果函数在组件中声明,则可能导致在每次渲染时调用该函数:
const Component = () => {
/*...*/
// New function declaration every render
const fetchBusinesses = () => {
fetch('/api/businesses/')
.then(...)
}
useEffect(() => {
fetchBusinesses();
}, [fetchBusinesses]);
/*...*/
}
因为每次用新的引用重新声明函数时。
正确的做法是:
const Component = () => {
/*...*/
// Keep the function reference
const fetchBusinesses = useCallback(() => {
fetch('/api/businesses/')
.then(...)
}, [/* Additional dependencies */])
useEffect(() => {
fetchBusinesses();
}, [fetchBusinesses]);
/*...*/
}
或者只是在useEffect中定义函数。
更多:[ESLint]关于'枯竭-deps' lint规则#14920的反馈