I have a server component that gets the initialAnswers, then it is sent through props in a client component that has an infinite scroll:
Page
├── AnswerForm (client comp)
│
└── AllAnswers (server comp)
├── getAnswers - server action (answers)
├── display totalAnswers
└── AllAnswersInfiniteScroll initialAnswers={answers}
└── Votes (client comp)
If I render the answers
in a server component, I can get the the update with a revalidatePath() in the server action, but it does not work in the client component.
So my question is, how do I get the client component to behave like a revalidatePath() in a server component?
Relevant bits of code:
The AllAnswers server component:
const AllAnswers = async ({ questionId, userId, totalAnswers, page, filter }: Props) => {
const { answers, isNext } = await getAnswers({
questionId,
page: page ? +page : 1,
sortBy: filter,
});
return (
<div className='mt-11'>
<div className='flex items-center justify-between'>
<h3 className='primary-text-gradient'>{`${totalAnswers} ${totalAnswers === 1 ? 'Answer' : 'Answers'}`}</h3>
<Filter filters={AnswerFilters} />
</div>
<AllAnswersInfiniteScroll
initialAnswers={answers}
questionId={questionId}
userId={userId}
isNext={isNext}
filter={filter}
/>
</div>
);
};
The AllAnswersInifiteScroll client component:
const AllAnswersInfiniteScroll = ({
initialAnswers,
questionId,
userId,
filter,
isNext,
}: Props) => {
const [allAnswers, setAllAnswers] = useState(initialAnswers);
const [isNextPage, setIsNextPage] = useState(isNext);
const pageRef = useRef(1);
const [ref, inView] = useInView();
const loadMoreAnswers = async () => {
const next = pageRef.current + 1;
const { answers: newAnswers, isNext } = await getAnswers({
questionId,
page: next,
sortBy: filter,
});
if (allAnswers?.length) {
setAllAnswers((prevAnswers) => [...prevAnswers, ...newAnswers]);
setIsNextPage(isNext);
pageRef.current = next;
}
};
const filterAnswers = async () => {
pageRef.current = 1;
const { answers: newAnswers, isNext } = await getAnswers({
questionId,
page: pageRef.current,
sortBy: filter,
});
setAllAnswers(newAnswers);
setIsNextPage(isNext);
};
useEffect(() => {
if (inView) {
loadMoreAnswers();
}
}, [inView]);
useEffect(() => {
filterAnswers();
}, [filter]);
return (
<>
//Here I map the answers and display them.
// In here I also have a Votes (client component)
</>
This is what confuses me, and can’t make it work with the votes / likes either:
The Votes and AnswerForm are both client components.
If I display the answers in the AllAnswers server component, I vote / like an answer -> it calls a server action that has revalidatepath() -> my vote / like answer is updated without me having to refresh the page.
But If I vote / like an answer, or I add a comment that is displayed after in a client component, revalidatePath() does not work? So then how do I make it behave “properly”?