如何解决`React Hook useEffect 缺少`react-hooks/exhaustive-deps` 的依赖项?
How to solve `React Hook useEffect has a missing dependency` of `react-hooks/exhaustive-deps`?
我来这里是想问一些关于 react hooks 和 missing 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]);
我来这里是想问一些关于 react hooks 和 missing 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]);