为什么我们要在 useIsMounted 挂钩中使用回调 return 挂钩中的引用?
Why would we useCallback in useIsMounted hook to return the ref from the hook?
以下示例取自 usehooks-ts 网站
import { useCallback, useEffect, useRef } from 'react'
function useIsMounted() {
const isMounted = useRef(false)
useEffect(() => {
isMounted.current = true
return () => {
isMounted.current = false
}
}, [])
return useCallback(() => isMounted.current, [])
}
export default useIsMounted
为什么我们 return isMounted.current
作为回调而不 return 只是值 isMounted.current
?
什么是 return 仅将 isMounted.current
作为值的示例?
您可以自己测试不同的实现,看看会发生什么:
const UnmountingChild = ({ unmount }) => {
const { isMounted, isMountedNC } = useIsMounted();
useEffect(() => {
console.log('IS MOUNTED BEFORE FETCH', isMounted()); // true
console.log('IS MOUNTED NO CALLBACK BEFORE FETCH', isMountedNC.current); //true
fetch('https://jsonplaceholder.typicode.com/todos/1').then((d) => {
console.log('IS MOUNTED', isMounted()); //false
console.log('IS MOUNTED NO CALLBACK', isMountedNC.current); //false
});
unmount(); // <-- This triggers the unmount of the component
}, []);
return <>Child</>;
};
function useIsMounted() {
const isMounted = useRef(false);
useEffect(() => {
isMounted.current = true;
return () => (isMounted.current = false);
}, []);
return {
isMounted: useCallback(() => isMounted.current, []),
isMountedNC: isMounted,
};
}
查看演示 HERE
回调的使用很有用,因为它可以让您在需要时直接读取 ref
和 ref.current
的值,如果您想要,只需调用 isMounted()
直接 return ref
你只需要确保 return 所有 ref
而不仅仅是 ref.current
因为如果你通过 ref.current
你会只传递实际值而不是 mutable ref object
,因此它的值将始终固定为 false
。
返回 ref
会强制您每次读取 .current
属性,这不是很好,它可能会误导人们在不知道内部实现的情况下使用 hook,同时调用 isMounted()
更好读,更好用,避免使用麻烦。
以下示例取自 usehooks-ts 网站
import { useCallback, useEffect, useRef } from 'react'
function useIsMounted() {
const isMounted = useRef(false)
useEffect(() => {
isMounted.current = true
return () => {
isMounted.current = false
}
}, [])
return useCallback(() => isMounted.current, [])
}
export default useIsMounted
为什么我们 return isMounted.current
作为回调而不 return 只是值 isMounted.current
?
什么是 return 仅将 isMounted.current
作为值的示例?
您可以自己测试不同的实现,看看会发生什么:
const UnmountingChild = ({ unmount }) => {
const { isMounted, isMountedNC } = useIsMounted();
useEffect(() => {
console.log('IS MOUNTED BEFORE FETCH', isMounted()); // true
console.log('IS MOUNTED NO CALLBACK BEFORE FETCH', isMountedNC.current); //true
fetch('https://jsonplaceholder.typicode.com/todos/1').then((d) => {
console.log('IS MOUNTED', isMounted()); //false
console.log('IS MOUNTED NO CALLBACK', isMountedNC.current); //false
});
unmount(); // <-- This triggers the unmount of the component
}, []);
return <>Child</>;
};
function useIsMounted() {
const isMounted = useRef(false);
useEffect(() => {
isMounted.current = true;
return () => (isMounted.current = false);
}, []);
return {
isMounted: useCallback(() => isMounted.current, []),
isMountedNC: isMounted,
};
}
查看演示 HERE
回调的使用很有用,因为它可以让您在需要时直接读取 ref
和 ref.current
的值,如果您想要,只需调用 isMounted()
直接 return ref
你只需要确保 return 所有 ref
而不仅仅是 ref.current
因为如果你通过 ref.current
你会只传递实际值而不是 mutable ref object
,因此它的值将始终固定为 false
。
返回 ref
会强制您每次读取 .current
属性,这不是很好,它可能会误导人们在不知道内部实现的情况下使用 hook,同时调用 isMounted()
更好读,更好用,避免使用麻烦。