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

时间:2019-11-27 11:08:23

标签: javascript reactjs warnings react-hooks eslint

我在这里要问有关反应挂钩缺少依赖项的问题。

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

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中建议的其他尝试,但是我从未在 useEffect 中看到来自 useReducer dispatcher 。 >

想法,谢谢!

2 个答案:

答案 0 :(得分:1)

在自定义挂钩中,您无法使用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]);

答案 1 :(得分:0)

您可以在自定义钩子自身内部使用useCallback来包装fetchCategories方法,并为其提供自己的依赖项数组。

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

我认为这是一种更抽象的方式。