Next.js Discord

Discord Forum

What is the best practice to create a component with useState and fetch? Client vs server component?

Unanswered
Kurilian Bobtail posted this in #help-forum
Open in Discord
Kurilian BobtailOP
How do I know what's best for a component between client and server component? I have a component that I want to use useState for, so I tried changing it to a client component as the resulting error message told me - but it's also async so that I can fetch the relevant data for the page, which I was then informed only works with server components. What is the usual way to go about making this kind of component? I assume there's a better implementation method.

17 Replies

Haddock
I think the best option for this is as follows:
keep the outer component as a server component (fetches data)
Kurilian BobtailOP
I'm also kind of assuming here that you don't immediately want a client component, going by the fact that you have to actively choose it
Haddock
and pass the fetched data as props to a nested client component, which can maange state
Kurilian BobtailOP
okay, that would make sense. I was starting to go in that direction in my head now. I will try that then and keep it in mind later as well!
Kurilian BobtailOP
Okay, I have another related question that I hope I can just put here - say I want to have a dropdown component inside this outer server component, so that I can update the state of the input. How do I best "send" that input data back to the parent server component to update info elsewhere on the page? Like if I want to change some text based on the selection in the dropdown?
Haddock
Server components don't react to client-side changes. so you don't send state back to the server component
fetch data in a server component, pass it to a client component, keep the dropdown and anything that changes because of it insde that client component.
if the change needs to affect server-rendered data, you can use server actions (to save/update data)
Cinnamon Teal
If you want to share the dropdown components data between some other sibling client components you would need to lift the state up to the nearest parent client component. So basically inside your server component you may have a client component which holds the React state, and the dropdown and the input would be children of that client component. Dropdown will receive the state and the state setter functions which it can call to update the state. The input will also read that same state. That is a common React pattern.

However, instead of state you can use the browser URL search params to store your data. This way you will have your server component, and the two child client components inside it. The dropdown can update the URL search params using client side hooks, and the server component can read that data and either consume the data it self or pass the data down to other client components. This is also a common pattern and much better than state, specially with filters and selections as it allows the user to bookmark or navigate between the browser history.
@Kurilian Bobtail is updating the URL params a common pattern? I feel like it wouldn't look very good to have it keep updating. Maybe it's just me...
Cinnamon Teal
It’s a common pattern. But whether or not it’s the better solution here depends on your setup and what you are actually trying to do.

Another option would be one of the client components to update the data in a database and revalidate the path. You can use a server action to do that. Then the parent server component refetches the data and passes the new data to the other client components.

But yeah, what the best solution would depend on what you actually are trying to do.
Kurilian BobtailOP
Could I also use a callback method and update the value directly in my server component? I would have to make it a var instead of a const since I can't use setState. Is that ever acceptable? It seems like everything is a const in React.
@Kurilian Bobtail How do I know what's best for a component between client and server component? I have a component that I want to use useState for, so I tried changing it to a client component as the resulting error message told me - but it's also async so that I can fetch the relevant data for the page, which I was then informed only works with server components. What is the usual way to go about making this kind of component? I assume there's a better implementation method.
How do I know what's best for a component between client and server component?


Usually your component tree will be inter-leaved with both server component and client component.

Its not as simple as: oh i want to use a useState at this innocent component, therefore i shall add "use client". Most of the time you will require creating 2 component to achieve what you wanted to do.

Most simple example is: using 1 server component to fetch data, pass it down to a client component that "enrich" it with various interactivity (therefore using useX hooks)
Could I also use a callback method and update the value directly in my server component?
You can't travel back from client-component to a server without making an "action"

You can do onClick method to update a store in which other client-components listens to, but would never change a server component (due to the inability of using hooks to listen to stores)

You can do onClick method to updates URL which triggers server-wide re-render and re-stitching which will change all changed components, both client and server to the latest props.

You can also hook a Server Action to your onClick method and call update() or refresh() which will also trigger a server-wide re-render and re-stitching of all updated components into the same DOM tree. (Meaning if component hasnt changed, then it wont re-render)
I would have to make it a var instead of a const since I can't use setState. Is that ever acceptable? It seems like everything is a const in React.

Server Components are NOT stateful therefore it can't hold state on its own but to rely on other states that is passed onto it. like URL/Routes/Cookies/Headers.

It is the purest form of UI = Component(props)

doesn't matter if you do const posts = [] and read it in a server component.

If you want to have a stateful and reactive component then you have to create a client-component.

This isn't to say that server component can't react to changes. it can. but the component itself doesn't know how to update unless you explicitly call them. Unlike client components. Not sure if that makes sense