You could test the different implementation yourself to see what happens:
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,
};
}
Check the demo HERE
The usage of a callback is useful because it lets you to read directly the value of the ref
with ref.current
when needed , simply by calling isMounted()
, if you want to directly return the ref
you just have to make sure to return all the ref
and not just ref.current
because if you pass ref.current
you will pass just the actual value and not the mutable ref object
hence its value will always be stuck to false
.
Returning the ref
forces you to then read every time the .current
property, and that's not very nice, and it could mislead people using the hook without knowing the internal implementation, while calling isMounted()
is nicer to read, and to use and avoids usage troubles.