【问题标题】:Adding exhaustive dependencies into useEffect and useCallback causes infinite loop将详尽的依赖项添加到 useEffect 和 useCallback 会导致无限循环
【发布时间】:2019-05-23 11:39:24
【问题描述】:

所以我以为我已经掌握了这些钩子的窍门,但 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

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

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 方法就会导致无限循环。

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

提前感谢您的帮助!

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    来自 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

    【讨论】:

    • 超级快速,一目了然。状态更新回调模式正是我所需要的。不知道你能做到这一点,但应该真的猜到了。非常感谢!
    猜你喜欢
    • 2020-02-26
    • 2021-09-27
    • 2020-07-18
    • 2021-07-25
    • 1970-01-01
    • 2021-01-14
    • 2021-01-08
    • 2021-05-23
    相关资源
    最近更新 更多