在 useEffect 和 useCallback 中添加详尽的依赖会导致无限循环 [英] Adding exhaustive dependencies into useEffect and useCallback causes infinite loop

查看:57
本文介绍了在 useEffect 和 useCallback 中添加详尽的依赖会导致无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

So I thought I was getting the hang of these hooks, but the lint rule react-hooks/exhaustive-deps is tripping me up.

我的 Provider

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

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

I'm allowing the rest of my app to access this by passing it into the value prop...

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

然后当路由改变时我从子组件调用这个方法

And then I'm calling this method from a child component when the route changes

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

上面的代码完全按照我的要求工作,我看不出这会导致任何错误.但是 eslint 告诉我:

The above code works exactly how I want, and I can't see this causing any bugs. However eslint is telling me:

React Hook useCallback 缺少依赖项:'screenState'.要么包含它,要么删除依赖数组

当我将 screenState 添加到数组中时,只要调用 onScreenChange 方法,它就会导致无限循环.

When I add screenState into the array, it causes an infinite loop as soon as the onScreenChange method is called.

现在发生循环的原因很明显,但我该如何停止并遵守规则"?

It's pretty obvious why the loop is now happening, but how do I stop this and "follow the rules"?

在此先感谢您的帮助!

推荐答案

来自 eslint 的警告似乎是正确的.如果多次调用 onScreenChange 方法,屏幕状态值将不会正确更新.您必须提供 screenState 作为对 useCallback

The warning from eslint seems to be correct. Since screenState value won't be updated correctly if the onScreenChange method is called multiple times. You must provide screenState as a depedency to useCallback

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

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

The other way to write the same code without adding the deps is to make use of state updater callback pattern

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


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

但是,如果您完全确定您尝试做的事情是正确的,您可以选择禁用 deps 警告.

However you may choose to disable the deps warning if you are absolutely sure what you are trying to do is correct.

您可以阅读以下帖子了解更多信息:

You may read below post for more inforamtion:

如何修复丢失的React Hook useEffect 中的依赖

这篇关于在 useEffect 和 useCallback 中添加详尽的依赖会导致无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆