I am created a comment section where i would like to be able to create a comment and immediately after display it in the comment section but i am not sure how to rerender the jsx after state changes. putting the state in the useEffect dependency creates an infinite loop. Help would be appreciated.
const Post = (props) => {
const [post, setPost] = useState([]);
const [comments, setComments] = useState([]);
const {id} = useParams();
useEffect(() => {
fetchData();
fetchComments();
}, [])
const fetchData = () => {
axios.get(`http://localhost:1234/api/posts/${id}`).then((res) => {
setPost(res.data);
}).catch((err) => {
console.log(err);
})
}
const fetchComments = () => {
axios.get(`http://localhost:1234/api/posts/${id}/comments`).then((res) => {
console.log(res)
setComments(res.data);
}).catch((err) => {
console.log(err);
})
}
console.log(comments)
return (
<div>
<div>thumbnail image</div>
<h1>{post.title}</h1>
<div>this is where body of post will go</div>
<CommentForm postId={post._id}/>
{comments.map((comment) => (
<Comment comment={comment.comment} username={comment.author.username} time={comment.timeStamp}/>
))}
</div>
)
}
2
Answers
Depending on how you’re creating a comment, it can depend. One rule of thumb when updating state, in the case of arrays as is the case with objects, you should treat them as immutable types. For example, if you’re updating the comments with
setComments
, opt forsetComments([...comments, newComment])
— using the spread syntax, orconcat
is preferred as it forces the return of a new object. SinceuseState
for object types is based on the reference, this approach will force a re-render on append.Update the comments array with the new comment and setComments to this new object. The component will re-render automatically.