在useEffect和useCallback中添加详尽的依赖关系会导致无限循环

时间:2019-05-23 11:39:25

标签: javascript reactjs react-hooks

所以我以为我已经抓住了这些钩子,但是皮棉规则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方法,它将导致无限循环。

显而易见,为什么现在会发生循环,但是如何停止循环并“遵循规则”?

在此先感谢您的帮助!

1 个答案:

答案 0 :(得分:2)

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]); 

编写相同代码而不添加deps的另一种方法是利用状态更新程序的回调模式

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


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

但是,如果您完全确定要执行的操作是正确的,则可以选择禁用deps警告。

您可以阅读下面的文章以获取更多信息:

How do I fix missing dependency in React Hook useEffect

相关问题