React Custom Hooks 和 useEffect 无限重新渲染

时间:2021-07-03 07:28:25

标签: reactjs react-hooks eslint

item_name

export const useMyCustomHook = () => { const uiLoad = useUiLoad(false); useEffect(() => { // ... }, [...]); } 是一个自定义钩子(很明显,uiLoad 也是如此)。这工作正常如果我没有将 useMyCustomHook 添加到 uiLoad 依赖数组。如果我确实包含它,它会无限地重新渲染。 这是我的 useEffect 钩子代码:

uiLoad

据我所知,钩子在重新渲染时不会改变。所以问题是:

  1. 为什么每次重新渲染时 uiLoad 都会改变?使用 useWhatChanged 调试器工具,我可以发现它确实在每次重新渲染组件时都会发生变化。钩子不是每次渲染都保持不变吗?或者这不适用于自定义钩子?

  2. 这里是使用 const baseDispatch = { type: SET_LOADING } export const useUiLoad = (initial: boolean = false) => { const dispatch = useDispatch<Dispatch<UIAction>>(); const loaded = useRef(false); useEffect(() => { if (initial && !loaded.current) { console.log('Called'); dispatch({ type: SET_LOADING, loadbarShowing: true }); loaded.current= true; } }, [dispatch, initial]) return (loading: boolean) => { const data: UIAction = { ...baseDispatch, loadbarShowing: loading } dispatch(data); } } 抑制警告的唯一解决方案吗?

1 个答案:

答案 0 :(得分:1)

每次渲染组件时都会调用钩子。 useUiLoad 每次被调用时都会返回一个 new 函数。你可以返回一个记忆化的函数,所以它是一个稳定的引用。

export const useUiLoad = (initial: boolean = false) => {
  const dispatch = useDispatch<Dispatch<UIAction>>();
  const loaded = useRef(false);

  useEffect(() => {
    if (initial && !loaded.current) {
      console.log('Called');
      dispatch({
        type: SET_LOADING,
        loadbarShowing: true
      });
      loaded.current= true;
    }
  }, [dispatch, initial]);

  return useCallback((loading: boolean) => {
    const data: UIAction = {
      ...baseDispatch,
      loadbarShowing: loading
    }
    dispatch(data);
  }, [dispatch]); // <-- add any other dependencies if necessary
}