ReactJS Async – Using React Context to simulate a Singleton?

I currently have a hook:

function useFollowUser() {
    const isFollowing = useRef(false);

    return (userId) => {
       if(isFollowing.current) return; // mutual exclusion

       isFollowing.current = true;

       ... update DB and GUI

       isFollowing.current = false;
    }
}

Then, I use it in my FollowButton component

function FollowButton({ userId }) {
   ...
   
   const followUser = useFollowUser();

   const handleOnPress = () => followUser(userId);
  
   return <Button onPress={handleOnPress} text=... />
}

The problem is that, if in the same screen I have two instances of the same component, with the same userId prop, there will be some data inconsistencies, as the followUser method, if the user press both buttons at the same time, might run in parallel.

In order to resolve this async issue, is a good option to move the hook logic to a Context provider?

Any other approach?

Answer

You could use context but simpler way is just to wrap isFollowing into same scope with self executing functions. Pay attention to two brackets that immediately invoke the function.

 const useFollowUser = (() => {
      let isFollowing = false;
    
      return () => {
     // this is hook context, you can use any effects here

        return (userId) => {
          if (isFollowing) return; // mutual exclusion
    
          isFollowing = true;
    
          // ... update DB and GUI
    
          isFollowing = false;
        };
      }
    })();

Usage:

const followUser = useFollowUser();