Is there any way to signal a Server Component to refetch?
I'm learning about the Server Components and I came across a scenario that I'm not entirely sure how to fix.
It's from this repository: https://github.com/vercel-labs/ai-chatbot, but the bottom line is that there's a Server Component that calls the server action getChats once the page loads, but I need to make this behavior happen again, like trigger a refetch once at least a message has been sent.
My question is: is it possible to trigger a Server Component to refetch/revalidate? I saw the revalidating docs, but I couldn't find an answer to make an specific component to do it, only the whole page.
Solution:Jump to solution
So what I'm guessing is that the only way to do it is to revalidatePath after sending the message, is that correct?So, to sum up, this is the correct way to fix this, right?...
28 Replies
I'm pretty sure you have to invalidate the whole route/route segment. It may seem weird but the way I understand it is that the fetched data isn't just linked to that component, but rather its position in the whole component tree.
If you were to try and revalidate that component, what would happen if you rendered multiple of them? How would you indicate which version of the component should revalidate?
In my head, the route segments act as 'markers' in the component tree, marking specific locations that are wrapped in suspense/error boundaries and can be refetched.
i have not been using next.js for a while, so i just havent fully understand server components, but can you use web sockets?
I cannot wrap my head around it yet. So I do have to revalidate the whole "page" if I want to update the component?
It's, like, a sidebar component
In my head, the route segments act as 'markers' in the component tree, marking specific locations that are wrapped in suspense/error boundaries and can be refetched.I'm not sure I understand this. When you say "specific locations", are those "locations" pages? If you're asking in my case, no. It's a request X that happens after Y only once. If this was trpc, I'd only need to invalidate the getChats request inside the onSuccess of the chat initiation
Yeah you'll need to invalidate the route segment, whether that's a page or a layout
How would I invalidate a layout? I couldn't understand that from the docs
pages/layouts, just places in the vdom tree. it's a weird way of thinking about it but it works for me
Whaaat
I don't think u can invalidate a layout that's alongside a page separately, only layouts for parent route segments
So.. I should have it inside /layouts instead of /components?
No /app is the only thing that matters
I think you can revalidate a layout and everything under it with
revalidatePath
Another way to think about this is that data is cached according to the route segment it was fetched in
When you use a server component inside a page.tsx
or layout.tsx
, you're essentially just copy-pasting the component from where you defined it into that specific route segment
And so that specific instance of the server component will have its data tied to that route segmentRight, so they are always tied to the route
Unless it's not a server component
Yeah data fetched in a server component is tied to the route in next
That's what I thought was the case. But then I feel like vercel's implementation of the side bar with a server component was a terrible idea
Why's that?
You've used chatgpt, right?
yea
I get what that component does, i've used their playground, i don't see what'd be wrong with it tho
You know when you start a new prompt and then the side bar immidietly creates a new chat?
What happens is:
1. user sends prompt
2. the api/chat/... endpoint now creates a new chat in the db
3. the endpoint streams the prompt answer to the user
If this was trpc, after sending the message, inside onSuccess, I'd invalidate the getChats so it queries again and shows the new chat
But with the structure they made, since the sidebar is a server component, I was wondering how I could implement that behavior.
So what I'm guessing is that the only way to do it is to
revalidatePath
after sending the message, is that correct?
That was my first guess, but that sounded weird and counter intuitive, especially for ReactYeah, looks like they do that for
clearChats
and removeChat
They don't do it for when u send a first message tho which is interestingI mean, it really feels weird to send a message and have the page reload.. or maybe this would happen too fast to notice? But in any case, it does feel like MVC which I hate lmao
The page isn't really reloading though, you're just fetching new data and rendering new markup
It's like fetching from an API except the API returns the HTML for that component instead of JSON that u client render
Also all the storage for that app is using KV so it's fast af
Ahhhhh got it
Wait, but that`s where my confustion come from
It's like fetching from an API except the API returns the HTML for that component instead of JSON that u client renderDoes it work like this because it'll only send the HTML of the parts that changed? Because remember, in the path I'm trying to revalidate, it contains all the components
It'll only send over the HTML for the server components that are being refetched
Client components stay where they are and aren't affected
in that route? I see
Well in that route + everything below it
Yeah
Solution
So what I'm guessing is that the only way to do it is to revalidatePath after sending the message, is that correct?So, to sum up, this is the correct way to fix this, right?
Ye pretty much
Got it, thank you so much Brendon