reactjs - React Custom Hooks 和 useEffect 无限重新渲染
问题描述
export const useMyCustomHook = () => {
const uiLoad = useUiLoad(false);
useEffect(() => {
// ...
}, [...]);
}
uiLoad
是一个自定义钩子(显然,是useMyCustomHook
)。如果我不添加uiLoad
到useEffect
依赖数组,这很好。如果我确实包含它,它会无限重新渲染。这是我的uiLoad
钩子代码:
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);
}
}
据我所知,钩子在重新渲染时不会改变。所以问题是:
为什么每次重新渲染时 uiLoad 都会发生变化?使用
useWhatChanged
调试器工具,我发现它确实在每次组件重新渲染时都会发生变化。钩子不是每次渲染都保持不变吗?或者这不适用于自定义钩子?这里唯一的解决方案是使用 抑制警告
// eslint-disable-next-line
吗?
解决方案
每次渲染组件时都会调用钩子。每次调用时都会useUiLoad
返回一个新函数。您可以返回一个记忆函数,因此它是一个稳定的参考。
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
}
推荐阅读
- spring - Spring Cloud Gateway 的 Cookie 路径
- c# - 自定义简单类型模型绑定器不适用于字符串修剪
- java - 如何从 aws s3bucket android 中删除文件?
- python - 如何从 matplotlib 图生成 shapefile?
- javascript - 如何找到非间接/嵌套的父母的孩子
- arduino - 在 Arduino 的 digitalWrite 中使用 volatile 关键字
- c# - 带有.net核心的控制台应用程序使用soap Web服务的问题
- angular6 - 首次加载无数据
- spring-boot - 是否可以使用 Spring Boot 对属性进行分组?
- yaml - 从 YAML OpenAPI 规范中删除一个字段