Reputation: 1496
I've got posts with comments and like to implement a post view that includes all comments to that post.
My getServerSideProps
passes the post
(including all comments) to my page. Whenever a new comment is written the comments should be dynamically updated, but I'm currently facing some problems with that.
My post view:
const PostView: NextPage = ({ post }) => {
return (
<Layout>
{post.title}
<CommentList initialComments={post.comments} postId={post.id} />
</Layout>
);
};
export default PostView;
export const getServerSideProps = () => {
const post = await getPost(); // returns the post and all its comments
return { props: { post } };
};
The CommentList
component:
const CommentList = (initialComments, postId) => {
const { data: comments } = useQuery(["comments", postId], async () => getComments(), { initialData: initialComments);
return (
<>
Comments: {comments.length}
... new comment form ...
... list of comments ...
</>
);
}
The reason why I still want to query comments with react-query
is simple: comments should be server-side rendered so that they become seo-relevant, while I want human users to get a dynamic list that can be updated.
When writing new comments I update the QueryClient
of react-query by hand:
export const useCreateCommentMutation = (postId: string) => {
const queryClient = useQueryClient();
return useMutation(
["comments", postId],
async (values) =>
await axios.post("/api/comments", values),
{
onSuccess: async res => {
queryClient.setQueryData<CommentWithAuthor[]>(
["comments", postId],
prev => [...(prev || []), res.data],
);
},
},
);
};
This seems to work at first glance; when I check the DOM the comments are included and when writing new comments they dynamically appear.
Unfortunately, when I refresh the page I get the following error:
Text content did not match. Server: "3" Client: "4"
3 (or 4) in this case is the comments.length
output.
What am I doing wrong in this case?
Thanks
Edit 1:
I've also tried fixing it by using useEffect
:
const [usedComments, setUsedComments] = useState([]);
useEffect(() => {
setUsedComments(comments || initialComments);
}, [comments])
And render usedComments
instead - but unfortunately now the comments are no longer part of the DOM.
Upvotes: 3
Views: 596
Reputation: 114
Why don't you try using useState() hook to store that the Comment data . Every time useQuery runs it will update the state which will cause re-rendering of the comment and also. I can't think of anything other then this. I don't know what your comment json/data look like to do the server side dynamic rendering.
And useQuery runs on user action like click on add new comment button or a time loop.
and your error seems like It is caused by some Server and client attribute of component.
Upvotes: 0