'Should useEffect have a dependency on the callback it will call (once)?

I have a function (loadJwt) I want to get called once upon phone startup to load something from the phone's keychain:

  const [user, setUser] = useState<User | null>(null);
  const [loading, setLoading] = useState(true);

  const loadJwt = useCallback(async () => {
    try {
      const value = await Keychain.getGenericPassword();
      if (value) {
        const phone_number = value.username;
        const jwt = JSON.parse(value.password);
        setUser({
          phoneNumber: phone_number,
          jwt: {
            accessToken: jwt.accessToken,
            refreshToken: jwt.refreshToken,
          }
        });
      }
    }
    catch (error) {
      console.error(`Keychain error: ${error}`);
      setUser(null);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    loadJwt();
  }, [loadJwt]);

Does useEffect need to have a dependency on this callback or could its dependency array just be empty?



Solution 1:[1]

With that specific callback, you don't need it, though your linter may not know that and may complain at you if you leave it out.

The reason you don't need it is that the callback doesn't use anything it closes over that isn't stable. It uses setUser, but setUser is guaranteed to be the same function for the lifetime of the component. You've also asked React to give you the first version of the callback every time, and while that's not a semantic guarantee (useCallback and useMemo are just performance optimizations), it's likely the callback won't change. But the important thing is that even if it does, it's harmless to call the older one instead of the newer one.

Moreover, I assume you don't want the effect to run any time except at the beginning when the component is mounted.

However, unless you use loadJwt somewhere else (in an event handler, etc.), I would just implement it inside the useEffect callback rather than separately.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 T.J. Crowder