React Hook useEffect 缺少依赖项:“dispatch”

2024-03-23

这是我第一次使用 React js ,我试图在离开此视图时删除警报,因为我不想在其他视图上显示它,但如果没有错误,我想保留成功警报以显示当我要重定向到另一个视图时

但我在 google chrome 上收到此警告Line 97:6: React Hook useEffect has a missing dependency: 'dispatch'. Either include it or remove the dependency array react-hooks/exhaustive-deps

如果我确实包含调度,我会得到无限循环

const [state, dispatch] = useUserStore();
useEffect(() => {
    let token = params.params.token;
    checktoken(token, dispatch);
  }, [params.params.token]);

  useEffect(() => {
    return () => {
      if (state.alert.msg === "Error") {
        dispatch({
          type: REMOVE_ALERT
        });
      }
    };
  }, [state.alert.msg]);

//response from the api
if (!token_valide || token_valide_message === "done") {
      return <Redirect to="/login" />;
    }

这是 useUserStore

  const globalReducers = useCombinedReducers({
    alert: useReducer(alertReducer, alertInitState),
    auth: useReducer(authReducer, authInitState),
    register: useReducer(registerReducer, registerInitState),
    token: useReducer(passeditReducer, tokenvalidationInitState)
  });
  return (
    <appStore.Provider value={globalReducers}>{children}</appStore.Provider>
  );
};

export const useUserStore = () => useContext(appStore);

更新 09/11/2020

不再需要此解决方案[email protected] /cdn-cgi/l/email-protection以上。

Now useMemo and useCallback可以安全地接收引用类型作为依赖项。#19590 https://github.com/facebook/react/pull/19590

function MyComponent() {
  const foo = ['a', 'b', 'c']; // <== This array is reconstructed each render
  const normalizedFoo = useMemo(() => foo.map(expensiveMapper), [foo]);
  return <OtherComponent foo={normalizedFoo} />
}

这是如何安全稳定(规范化)回调的另一个示例

const Parent = () => {
    const [message, setMessage] = useState('Greetings!')

    return (
        <h3>
            { message }
        </h3>
        <Child setter={setMessage} />
    )
}

const Child = ({
    setter
}) => {
    const stableSetter = useCallback(args => {
        console.log('Only firing on mount!')
        return setter(args)
    }, [setter])

    useEffect(() => {
        stableSetter('Greetings from child\'s mount cycle')
    }, [stableSetter]) //now shut up eslint

    const [count, setCount] = useState(0)

    const add = () => setCount(c => c + 1)

    return (
        <button onClick={add}>
            Rerender {count}
        </button>
    )
}

现在具有稳定签名的引用类型,例如来自useState or useDispatch可以安全地在效果内使用而无需触发exhaustive-deps即使来自props

---

旧答案

dispatch来自习俗hook因此它没有稳定的签名,因此会在每次渲染时发生变化(引用相等)。通过将处理程序包装在useCallback hook

   const [foo, dispatch] = myCustomHook()
  
   const stableDispatch = useCallback(dispatch, []) //assuming that it doesn't need to change

   useEffect(() =>{
        stableDispatch(foo)
   },[stableDispatch])

useCallback and useMemo是辅助钩子,主要目的是添加额外的层依赖性检查以保证同步性。通常您想与useCallback以确保稳定的签名prop你知道如何改变,而 React 不会。

A function(引用类型)通过props例如

const Component = ({ setParentState }) =>{
    useEffect(() => setParentState('mounted'), [])
}

假设您有一个子组件,在安装时必须在父组件中设置某种状态(不常见),上面的代码将生成一个关于未声明依赖项的警告useEffect,所以让我们声明setParentState作为 React 检查的依赖项

const Component = ({ setParentState }) =>{
    useEffect(() => setParentState('mounted'), [setParentState])
}

现在,此效果在每个渲染上运行,不仅在安装时运行,而且在每次更新时运行。发生这种情况是因为setParentState is a function每次函数都会重新创建Component被叫。你懂的setParentState不会随着时间的推移改变它的签名,所以可以安全地告诉 React。通过将原始助手包装在useCallback您正在这样做(添加另一个依赖项检查层)。

const Component = ({ setParentState }) =>{
   const stableSetter = useCallback(() => setParentState(), [])

   useEffect(() => setParentState('mounted'), [stableSetter])
}

就这样吧。现在React知道stableSetter不会在生命周期内更改它的签名,因此效果不需要不必要地运行。

附注useCallback它也被用来像useMemo,优化昂贵的函数调用(记忆)。

的两个主要目的useCallback are

  • 优化依赖引用相等的子组件,以防止不必要的 呈现。Font https://reactjs.org/docs/hooks-reference.html#usecallback

  • 记住昂贵的计算

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

React Hook useEffect 缺少依赖项:“dispatch” 的相关文章

随机推荐