reactjs - 详尽的-deps 规则不将自定义钩子的结果识别为 React 参考
问题描述
想象一个钩子:
export function useMounted() {
const mounted = React.useRef<boolean>(false);
React.useEffect(() => {
mounted.current = true;
return () => {
mounted.current = false;
};
}, []);
return mounted;
}
我想使用那个钩子来确定组件是否仍然安装。它的一个用例是仅在浏览器获取并缓存图像时才异步加载图像并显示图像。这种用例的简化版本可以是:
function useLazyImage(src: string, triggerCallback: any) {
const mounted = useMounted();
const image = useRef<HTMLImageElement>();
useEffect(() => {
if (!!src) {
image.current = new Image();
image.current.onload = () => {
if (mounted.current)
triggerCallback();
};
image.current.src = src;
return () => {
image.current = undefined;
};
}
return undefined;
}, [src]);
}
它不包括错误处理,也不处理 triggerCallback 的更改,但它显示了我的问题。react-hooks/exhaustive-deps 警告我缺少mounted
依赖项,即使它不应该 afaik。因为mounted
是 Ref,通过使用它,我不会意外关闭过时的范围,而 eslint 实际上知道这一点。如果我将代码更改为
function useLazyImage(src: string, triggerCallback: any) {
const mounted = React.useRef<boolean>(false);
React.useEffect(() => {
mounted.current = true;
return () => {
mounted.current = false;
};
}, []);
const image = useRef<HTMLImageElement>();
eslint 不再警告我了。ESLint 的这种限制是它无法知道我的自定义钩子的结果是什么,还是我做错了,并且潜伏着一个错误?
解决方案
在您的第一个示例中,您从useMounted
创建它的函数返回 ref。因此引用被泄露,因此可能会被更改。在您的底部示例中,引用被创建为函数本地值,因此不是组件状态的一部分。这就是为什么您没有看到底部示例的警告。
推荐阅读
- python - OpenGL绘制区域仅占据可用窗口的左下象限
- java - 使用Java中的do-while循环查找序列的所有元素的总和,以数字0结尾
- macos - 在 Ubuntu 服务器上安装 Mac-OS
- apache-spark - PySpark:带前缀/后缀的选择
- python - Django:帮助理解信号函数
- java - 在 Android 的另一个 Activity 中启动 Activity
- python - 如何不收到“无类型”错误消息
- python-3.x - 在 Python 中使用 tkinter 添加滚动条后如何控制框架的宽度、高度和位置?
- python - 未找到“您的选择”的反向。'yourchoice' 不是有效的视图函数或模式名称
- javascript - 导入语法 React Redux