父组件重新渲染useEffect

时间:2020-01-03 14:45:12

标签: reactjs

我有一个名为Posts的父组件,该组件具有useEffect并获取数据,然后我有一个名为Post的子组件,该子组件从props中渲染该帖子。我在Post中有一个delete and like函数,当希望发贴或删除post时,我希望父母重新呈现。我该如何实现?

╒══════════════════╕
│"n"               │
╞══════════════════╡
│{"name":"Abigail"}│
├──────────────────┤
│{"name":"Bailee"} │
└──────────────────┘

2 个答案:

答案 0 :(得分:1)

我建议您在子onUpdate组件上有一个附加的prop方法(<Post />),只要触发deletePost()like()就会触发该方法。 / p>

const Posts = () => {
  const [posts, setPosts] = useState([]);

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

  const getPosts = async () => {
    const data = await fetch('https://localhost:1111/api/posts/posts', {
      credentials: 'include'
    });
    const response = await data.json();
    console.log(response);
    setPosts(response);
  };

 const handleUpdate = () => {
   getPosts();
 }

  return (
    <div>
      {posts.map(post => (
        <Post key={post.id} onUpdate={() => handleUpdate()} post={post} />
      ))}
    </div>
  );
};

const Post = props => {
  const { onUpdate } = props;

  const like = async post => {
    const formData = new FormData();
    formData.append('id', post);
    const data = await fetch('https://localhost:1111/api/posts/like', {
      method: 'POST',
      body: formData,
      credentials: 'include'
    });

    const response = await data.json();
    console.log(response);

    onUpdate();
  };

  const deletePost = async post => {
    const formData = new FormData();
    formData.append('id', post);
    const data = await fetch('https://localhost:1111/api/posts/deletepost', {
      method: 'POST',
      body: formData,
      credentials: 'include'
    });

    const response = await data.json();
    console.log(response);

    onUpdate();
  };

  return (
    <div>
      <img
        src={`http://localhost:1111/api/posts/uploads/images/${props.post.content}`}
        alt={`Post ${props.post.id}`}
      />
      <button onClick={() => like(props.post.id)}>Like</button>
      <button onClick={() => deletePost(props.post.id)}>Delete</button>
    </div>
  );
};

如您所见,onUpdate()deletePost()like()的末尾都被调用,在父帖子组件中,handleUpdate()将被调用,在turn提交获取响应以更新posts状态。这将导致父<Posts />重新渲染。

答案 1 :(得分:0)

保留父组件内部的发布功能,并将更新功能传递给Post

const Posts = () => {
  const [posts, setPosts] = useState([])

  useEffect(() => {
    fetch('https://localhost:1111/api/posts/posts', {
      credentials: 'include',
    })
      .then(res => res.json())
      .then(setPosts)
  }, [])

  const likePost = async postId => {
    await fetch...
    setPosts(prevState =>
      prevState.map(post =>
        post.id === postId
          ? {
              ...post,
              likes: post.likes + 1,
            }
          : post
      )
    )
  }

  const deletePost = async postId => {
    await fetch...
    setPosts(prevState => prevState.filter(post => post.id !== postId))
  }

  return (
    <div>
      {posts.map(post => (
        <Post
          key={post.id}
          post={post}
          likePost={likePost}
          deletePost={deletePost}
        />
      ))}
    </div>
  )
}

const Post = ({ post, likePost, deletePost }) => (
  <div>
    <img
      src={`http://localhost:1111/api/posts/uploads/images/${post.content}`}
      alt={`Post ${post.id}`}
    />
    <button onClick={() => likePost(post.id)}>Like</button>
    <button onClick={() => deletePost(post.id)}>Delete</button>
  </div>
)