如何解决`React Hook useEffect 缺少`react-hooks/exhaustive-deps` 的依赖项?

How to solve `React Hook useEffect has a missing dependency` of `react-hooks/exhaustive-deps`?

我来这里是想问一些关于 react hooksmissing dependencies.

我尽量简洁,这是我控制台中的警告消息

Compiled with warnings.

./src/views/categories/Categories.tsx
  Line 14:6:  React Hook useEffect has a missing dependency: 'dispatcher'. Either include it or remove the dependency array  react-hooks/exhaustive-deps

钩子的代码useEffect

const [categoriesList, dispatcher] = useCategoryList({})

useEffect(() => {
  !isOpenConfirmAddModal && dispatcher.fetchCategories()
}, [isOpenConfirmAddModal])

这是自定义挂钩的代码 useCategoryList

export const useCategoryList = (
  initialState: CategoriesData
): CategoriesListHook => {
  const [state, dispatch] = useReducer(categoryReducer, initialState)

  const fetchCategories = async () => {
    const categories = await getCategories()
    dispatch({ type: FETCH_CATEGORIES, data: categories })
  }

  // ....

  return [
    state,
    {
      fetchCategories
      // ...
    }
  ]
}

如果我将调度程序设置为依赖项

useEffect(() => {
  !isOpenConfirmAddModal && dispatcher.fetchCategories()
}, [isOpenConfirmAddModal, dispatcher])

并且应用程序中的效果是对dispatcher.fetchCategories()的调用的永恒循环,似乎dispatch在不断更新自己并且循环永无止境。

我尝试了 SO 中建议的其他一些尝试,但我从未在 useReducer 中看到 dispatcher =]useEffect.

想法,谢谢!

您可以在自定义挂钩本身内部使用 useCallback 来包装 fetchCategories 方法,从而提供自己的依赖项数组。

const fetchCategories = useCallback(async () => {
  const categories = await getCategories()
  dispatch({ type: FETCH_CATEGORIES, data: categories })
},[<your dependencies>])
// check and update this dependency array

我认为这样做更抽象。

在您的自定义挂钩中,您无法使用 useMemo 重新创建 fetchCategories 和可能的其他方法:

export const useCategoryList = initialState => {
  const [state, dispatch] = useReducer(
    categoryReducer,
    initialState
  );

  const methods = React.useMemo(
    () => ({
      fetchCategories: async () => {
        const categories = await getCategories();
        dispatch({
          type: FETCH_CATEGORIES,
          data: categories,
        });
      },
      //other methods
    }),
    []//no dependencies
  );

  return [state, methods];
};

现在,fetchCategies 在组件生命周期内不应更改,因此您可以:

const [categoriesList, {fetchCategories}] = useCategoryList({});
useEffect(() => {
  !isOpenConfirmAddModal && fetchCategories();
}, [fetchCategories]);