我在这里要问有关反应挂钩和缺少依赖项的问题。
我尽量简洁,这是控制台中显示的警告消息
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 。 >
想法,谢谢!
答案 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
我认为这是一种更抽象的方式。