Reputation: 2661
Note: in this project, we are not using Redux.
I have a stack profile screen with a simple button "Follow user" and a counter "Followers".
A user can navigate to this stack profile screen, and close it whenever he wants.
If the user press the "Follow" button:
3.1 The button will perform a connection to my server, in order to run the logic for "following user"
3.2 Then, when this action is done, to re-render the screen (the other user's followers counter), I am updating the other user's data (state of the profile screen), increasing his followers counter.
3.3 When this state is updated, a useEffect will run and add the new other user data to a map that I have in a context (in which I 'store' users in a visitedUsers map, in order to avoid requesting the database every time I visit the profile of a user I have recently visited, and preserve the correct data between multiple profile screens of the same user in different tabs of the app (some kind of non-persistant local memory and state manager)).
Steps 3.1, 3.2 and 3.3 always have to run, in order to ensure the app data consistency. But... the user can close the screen during the asynchronous job... so, steps 3.2 and 3.3 might not run.
Here is a diagram which shows the issue:
As you can see, if the profile screen is unmounted, the setState and useEffect (which updates the context) will not run and might causes memory leaks.
How can I solve this issue??
The "isMounted" anti-pattern is not a good option because steps 3.2 and 3.3 always have to run.
It seems that I need to move this logic up into the components hierarchy (what I have thought to do, but seems really strange)... is this the only way?
Any ideas?
Upvotes: 0
Views: 145
Reputation: 232
I had a similar problem once. I was trying to start an upload but allow the user navigate away from the component while the upload was running. My solution was a bit roundabout but, well, it worked.
So what I did was move the upload function to the root component (App.js, not index.js!) and instead of using Redux, I used ContextAPI and set a useEffect hook that would listen to changes in the data stored and, each time the data changed, it would trigger the upload function using the new data it finds. That way, the actual upload is not handled by the component it was initiated from and the user is free to navigate elsewhere without interrupting the upload. The only way to interrupt it would be to close the app.
Upvotes: 3