Why does useIsMounted return a callback instead of the value itself?

253 Views Asked by At

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?

1

There are 1 best solutions below

0
On BEST ANSWER

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>;
}

Edit why-does-useismounted-return-a-callback-instead-of-the-value-itself

Seems it was just a design decision to return a memoized function.