lundi 6 septembre 2021

Patterns for fetches memoizations in React

In my app I have a folder "api", in which I have all the necessary methods to communicate with my backend.

For example:

api/db/users/getUserData.js

export default async (userId) => {
   ...
} 

I also have a module "usersCache.js", which provides the add, update, get and delete methods, in order to access a cache of users.

When getting a user data in the getUserData method I have described, I am using the typical memoization pattern:

api/db/users/getUserData.js

export default async (userId) => {
   if(!usersCache.isUserCached(userId)) {
      // const userData = get user data from backend
      usersCache.add(userId, userData);
   }

   return usersCache.get(userId);
} 

This seems simple and clean for me, but the problem is that I have some components in my code that need to access that cache for storing data.

For example, my "EditProfile" component is a form which just provides the new user edited data to a cloud function. As the user data is new, then the EditProfile form will have to store it in the cache of users (update the current user's cached data)

function EditProfile() {
    const currentUser = useCurrentUser(); // consume current user context 

    const [newData, setNewData] = useState(currentUser.data);

    const submit = async () => {
        try {
           // await  ... connect to server

           // Update the user data in context to produce re-renders of consumers
           currentUser.updateData(newData)
           
           // Update the user data in cache
           usersCache.update(currentUser.data.id, newData);
        } 
        catch(err) {
           toast.show(err);
        }
    }

}

As you can see, I am updating the current user context, which cannot work as a cache because it will be unmounted when the user signs out, to produce a re-render in all components that consumes it, in order to and have consistent information in all screens.

But... accessing the cache of my "api" (the interface I am using in the frontend to communicate with the backend) inside React components seems really strange to me.

I have never done this before, it is my first time memoizing data, and I have seen people using a custom hook "useFetch", to perform of these kinds of operations.

I am a bit anguished and scared if I am building a paranoia in my code, since I have tried to use that hook, but the truth is not very adaptable to Firestore Cloud Functions, and somehow I have adapted my code to it with the structure that I commented at the beginning.

I honestly don't know if this type of organization has a specific name or if there is some kind of documentation to read about it. But, really, I'm not convinced at all about manipulating an interface cache from a component, is it some anti-pattern? Any ideas to organize my code better?

Thanks.

Aucun commentaire:

Enregistrer un commentaire