想象一个钩子:
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 的限制是它无法知道我的自定义钩子的结果是什么,还是我做错了并且存在潜伏的错误?