React - Synchronize posts deletions between routes

Viewed 25

Introduction

I am implementing an Instragam clone.

I have 2 screens:

  1. PostsFeed
  2. UserPosts

As a user can delete posts, like posts, etc. I have decided to store the posts in a context "UserPostsContext", in order to synchronize all my routes.

export function PostsProvider({ children }) {
  const [posts, dispatch] = useReducer(contentsReducer, initialState);

  ...
  
  const addPosts = (post) => dispatch(...); // Add posts to the respective **users** posts list (sorted by date)

  const addUserPosts = (userId, posts) => ... // Add posts to the respective **user** posts list (sorted by date)

  const getUserPosts = (userId) => posts[userId] ?? [];

  return (
      <PostsContext.Provider value={{ ..., getUserPosts }}>
         {children}
      </PostsContext.Provider>
  );
}

My stateful data looks like:

{
    userId1: [
        { id: "post1", totalLikes: 10, ... },
        { id: "post2", totalLikes: 1, ... },
        ...
    ],
    userId2: [
        { id: "post1", totalLikes: 50, ... },
        { id: "post2", totalLikes: 100, ... },
        ...
    ],
}

This way, if the user deletes a post, the code will just update the PostsProvider state, and all the routes will be synchronized correctly. Or, also, if the "totalLikes" of one post is increased, the respective mounted Cards will be updated too. That is cool.

My idea to consume the context in the routes

I have no idea about how to use this context correctly in both screens.

My idea was:

 + For the feed screen:

 1.1 Fetch random user posts sorted by engagement in my "PostsFeed" screen.
 1.2 Add these posts to the PostsContext, using the addPosts() method.
 

 + For the user posts screen:
 
 2.1 Fetch user posts from the DB, sorted by date
 2.2 Add these posts to the PostsContext, using the addUserPosts() method

But... where should I consume it?

I mean, if I need to get all posts deletions synchronized, when the current user deletes a post from the PostsFeed screen (imagine that his post appears there) the UserPosts screen of the current user (imagine it is mounted in the app tab navigator) has to synchronize its data with the performed action, I mean, the deleted post has to disappear from the current user UserPosts screen too.

So... my mind is saying to me that my UserPosts screens should looks like:

function UserPosts({ userId }) {
   const posts = usePosts(); // Consume the context

   const data = posts.getUserPosts(userId); // <---- Get the user sorted posts from the context
   const [isLoading, setIsLoading] = useState(true);
   const [error, setError] = useState(undefined);

   const cursor = useRef(new Date());

   const getPosts = async (limit = 10) => { 
      ...
 
      const { posts, newCursor } = await api.getPosts(userId, cursor.current, limit);
      posts.addUserPosts(userId, posts); // Add the fetched posts to the context
      cursor.current = newCursor;

      ...
   }

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

   return <CardList data={data} loading={isLoading} onEndReached={getPosts} />
}

And not like this (without consuming, handling the stateful data inside the component):

function UserPosts({ userId }) {
   const [posts, setPosts] = useState([]); // <--- Local state
   const [isLoading, setIsLoading] = useState(true);
   const [error, setError] = useState(undefined);

   const cursor = useRef(new Date());

   const getPosts = async (limit = 10) => { 
      ...
 
      const { posts, newCursor } = await api.getPosts(userId, cursor.current, limit);
      setPosts((prevPosts) => [...prevPosts, ...posts]); // Add the fetched posts to the state
      cursor.current = newCursor;

      ...
   }

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

   return <CardList data={posts} loading={isLoading} onEndReached={getPosts} />
}

Main problem

But... what about if the feed screen has stored some random posts in the empty user posts list (context data)?? Then, the UserPosts screen, before fetching the user posts, will be displaying this few stored posts of the context.

Also, what if the user deletes the post from the UserPosts screen instead of from the PostsFeed? Then, the PostsFeed, which renders a list of random user posts, has to be able to remove the deleted post from its list (UI)...

I am not able to figure out a way to meet my requirements, to share the state between the two screens without affecting the paging of data or the fetches and subsequent renderings, to be able to synchronize the deletions throughout my app.

Any ideas? Thank you.

0 Answers
Related