在 useEffect 和 useCallback 中添加详尽的依赖项会导致死循环

Adding exhaustive dependencies into useEffect and useCallback causes infinite loop

所以我以为我已经掌握了这些钩子的窍门,但是 lint 规则 react-hooks/exhaustive-deps 却把我绊倒了。

我的Provider

里面有这个方法
const onScreenChange = useCallback(
(key, value) => {
  const newState = Object.assign({}, screenState, { [key]: value });
  localStorage.setItem('screens', JSON.stringify(newState));
  setScreenState(newState);
},
[]); // screenState

我允许我的应用程序的其余部分通过将其传递到值属性来访问它...

return <Provider value={{onScreenChange, ... }}>children</Provider>

然后我在路由更改时从子组件调用此方法

useEffect(() => {
   if (match.path === `/${screenKey}`) {
     onScreenChange(screenKey, 'external');
   }
}, [onScreenChange, match.path, screenKey]);

以上代码完全符合我的要求,我看不出这会导致任何错误。然而 eslint 告诉我:

React Hook useCallback has a missing dependency: 'screenState'. Either include it or remove the dependency array

当我将 screenState 添加到数组中时,一旦调用 onScreenChange 方法就会导致无限循环。

现在循环发生的原因很明显,但我该如何停止循环"follow the rules"?

在此先感谢您的帮助!

eslint 的警告似乎是正确的。如果 onScreenChange 方法被多次调用,screenState 值将无法正确更新。您必须提供 screenState 作为对 useCallback

的依赖
const onScreenChange = useCallback(
(key, value) => {
  const newState = Object.assign({}, screenState, { [key]: value });
  localStorage.setItem('screens', JSON.stringify(newState));
  setScreenState(newState);
},
[screenState]); 

在不添加依赖的情况下编写相同代码的另一种方法是使用状态更新器回调模式

const onScreenChange = useCallback(
(key, value) => {


  setScreenState(oldState => {
       const newState = Object.assign({}, oldState, { [key]: value });
       localStorage.setItem('screens', JSON.stringify(newState));
       return newState;
  });
},
[]); 

但是,如果您绝对确定您正在尝试做的事情是正确的,您可以选择禁用 deps 警告。

您可以阅读下文 post 了解更多信息: