Lygis
Lygis

Reputation: 100

react/ state not being updated because of cleanup

I have custom hook that adds user info for posts created. And if I don't add cleanup it works as intended. I create new post, press post and it gets added to screen, but with if(mounted.current)setState() it does not update, only on refresh. What could be the problem and how could I fix it?

const AllPostsAssign = () => {
  const { userPosts, allUsers } = useData();
  const [posts, setPosts] = useState();
  const mounted = useRef(true);

  // map existing posts and add user object and post id into post object.
  useEffect(() => {
    const postsWithUsers = allUsers.map((y) => {
      const usersAssignedToPosts = userPosts.map((x) => {
        if (y.userId === x.data().userId) {
          const q = Object.assign(x.data(), { id: x.id });
          const z = Object.assign(q, { user: y });
          return z;
        }
      });
      return usersAssignedToPosts;
    });
    const noUndefined = postsWithUsers.flat().filter((post) => post);

// without mounted.current it works.
    if (noUndefined && mounted.current) setPosts(noUndefined);

    console.log(mounted.current);
    console.log(posts);

    return () => (mounted.current = false);
  }, [userPosts, allUsers]);

  // sort by time created and then reverse, so newest posts would be on top.
  posts &&
    posts.sort((a, b) => {
      return a.createdAt.seconds - b.createdAt.seconds;
    });
  posts && posts.reverse();
  return posts;
};

export default AllPostsAssign;

Upvotes: 0

Views: 70

Answers (1)

ale917k
ale917k

Reputation: 1768

Have your mounted check declared directly inside your useEffect, as such:

  useEffect(() => {
   let mounted = true;

    const postsWithUsers = allUsers.map((y) => {
      const usersAssignedToPosts = userPosts.map((x) => {
        if (y.userId === x.data().userId) {
          const q = Object.assign(x.data(), { id: x.id });
          const z = Object.assign(q, { user: y });
          return z;
        }
      });
      return usersAssignedToPosts;
    });
    const noUndefined = postsWithUsers.flat().filter((post) => post);

// without mounted.current it works.
    if (noUndefined && mounted) setPosts(noUndefined);

    console.log(mounted);
    console.log(posts);

    return () => (mounted = false);
  }, [userPosts, allUsers]);

Upvotes: 1

Related Questions