INTRODUCTION
I am trying to emulate the typical social networks behavior, where when the user deletes one of his posts, it is automatically deleted in all the app routes. Just see the behavior behind Instagram or TikTok.
So, I have decided to put all the users posts in a context:
export function UserPostsProvider({ children }) {
const [posts, dispatch] = useReducer(userPostsReducer, initialState);
const addUserPosts = (userId, posts, unshift = false) => {
dispatch(actionCreators.addUserPosts(userId, posts, unshift));
};
const deleteUserPost = (userId, postId) => {
dispatch(actionCreators.deleteUserPost(userId, postId));
};
const getUserPosts = (userId) => posts[userId] ?? [];
return (
<UserPostsContext.Provider
value={{
addUserPosts,
deleteUserPost,
getUserPosts,
}}
>
{children}
</UserPostsContext.Provider>
);
}
So, when the user enters another user profile, the posts will be added to this context. Also, when he scrolls down his own endless list of posts, to delete one of his old publications, all the fetched posts (from the database) will be added to the context too.
With this, I am able to delete the posts having a synchronization between all my routes. But... what about RAM and performance?
PROBLEM
I have detected one PRO and one CONS with this solution:
PRO:
As the all the fetched posts are located inside the context, we can avoid fetching contents that was previously fetched, converting the Context in some kind of in-memory cache.
CONS:
When the stack screen of another user profile is unmounted, the posts are not deleted from the context... RAM will increase linearly by the pass of the time.
How can I solve this issue? Any ideas?
Because, if in my components, I just do:
function UserPosts({ userData }) {
const postsContext = useContext(UserPostsContext);
const posts = postsContext.getUserPosts(userData.id);
const getMorePosts = () => {
... getting posts from DB with pagination
}
return <CardList data={posts} ... />
}
I will not be able to implement a data pagination at all (only if the posts are not stored in the database), as I am getting all the user posts at once from the context, and the FlatList will render all of them, causing a big performance issue.
CodePudding user response:
As discussed in the comments to your question.
My recommendation would be to use sockets for something like this instead of storing everything in context. Instead context should only be used for things that are truly global and for other things like comments/likes you should instead use sockets to update the incoming/outgoing messages. For example building a little "comment" or "message" component and letting each of them subscribe to their own socket.
What's more is that if you're working with something like "likes" or "comments" then the only way to get it to update in real time is using sockets or spamming your backend with constant requests.
For that you'll need to add sockets to your API, so in a route like "comment/9283012/like" or whatever, you can publish a "like" event (or whatever) that the other users or a specific user can listen to, which in return will update the specific "comment" or "message" component that you created.
CodePudding user response:
Two suggestions:
use pagination instead of loading all the posts in one request. with scroll down/scroll up, the new requests will send to the server and get the tail of data. for example, you can get the old post with an offset of 10 posts per request or more. also with CDN cash and a proper cash policy you can manage a pro application like Instagram.
you can define a method (action) to clear the context value on page unload in the
useEffect
clean up function:
for example:
useEffect(() => {
return () => // here call the cleaner function
}, [])