I'm referring to useIsMounted
from usehooks-ts. I'm trying to understand why the function is returning useCallback(() => isMounted.current, [])
instead of just isMounted.current
.
I've tested both ideas in a CodeSandbox that just uses a setTimeout
to simulate async work and I haven't found any issues returning the value instead of a callback. What am I missing?
For whatever reason the authors of this useIsMounted
hook decided to return a function instead of the boolean isMounted
value. The returned function is memoized so it can be safely passed as a callback to children components.
Returning isMounted.current
doesn't work though, but returning the entire isMounted
ref does.
Example:
const useIsMounted = () => {
const isMounted = useRef(false);
useEffect(() => {
isMounted.current = true;
return () => {
isMounted.current = false;
};
}, []);
return isMounted;
}
And this requires consumers to know it's a React ref and that they need to unpack the current ref value.
function Child() {
const [data, setData] = useState("loading");
const isMounted = useIsMounted();
// simulate an api call and update state
useEffect(() => {
void delay(3000).then(() => {
if (isMounted.current) setData("OK"); // <-- access ref value
});
}, [isMounted]);
return <p>{data}</p>;
}
Seems it was just a design decision to return a memoized function.