How would you solve this?
Answered
Dutch posted this in #help-forum
DutchOP
I want a page with a stepper at the top, and each step has corresponding content displayed below it.
So obviously the page needs to be "use client" for the state.
I want to also make api calls, for example in the first step I want to check if the user is already logged in, and then skip that step.
These should obviously be in a servercomponent.
But I cant make the content components serverside, because the page itself must be client side in order to have its state determine what step the stepper should display, and the corresponding content component.
It seems to me this is impossible, but it must be possible right?
So obviously the page needs to be "use client" for the state.
I want to also make api calls, for example in the first step I want to check if the user is already logged in, and then skip that step.
These should obviously be in a servercomponent.
But I cant make the content components serverside, because the page itself must be client side in order to have its state determine what step the stepper should display, and the corresponding content component.
It seems to me this is impossible, but it must be possible right?
Answered by B33fb0n3
One thing, that you can do is, that you fetch the important parts serverside and then pass it down to the actual stepper component. When the stepper component is then mounted, the next step will be calculated. Like that you already start at step 2 or 3 or whatever you calculate based on the data
21 Replies
@Dutch I want a page with a stepper at the top, and each step has corresponding content displayed below it.
So obviously the page needs to be "use client" for the state.
I want to also make api calls, for example in the first step I want to check if the user is already logged in, and then skip that step.
These should obviously be in a servercomponent.
But I cant make the content components serverside, because the page itself must be client side in order to have its state determine what step the stepper should display, and the corresponding content component.
It seems to me this is impossible, but it must be possible right?
One thing, that you can do is, that you fetch the important parts serverside and then pass it down to the actual stepper component. When the stepper component is then mounted, the next step will be calculated. Like that you already start at step 2 or 3 or whatever you calculate based on the data
Answer
Sun bear
You could also use tanstack query for example and just fetch the data from the client.
Example:
- user is at step 1. User data is fetched. You show a loading state and then either go to step two or show a login form.
You could trigger it for every step. Maybe in step 3 you want to fetch data based on step 2 etc etc
Example:
- user is at step 1. User data is fetched. You show a loading state and then either go to step two or show a login form.
You could trigger it for every step. Maybe in step 3 you want to fetch data based on step 2 etc etc
@B33fb0n3 One thing, that you can do is, that you fetch the important parts serverside and then pass it down to the actual stepper component. When the stepper component is then mounted, the *next* step will be calculated. Like that you already start at step 2 or 3 or whatever you calculate based on the data
DutchOP
the only issue is that ideally, is want to have the content part in a <Suspense>, which I cant do if I am waiting to fetch the data before I display the page^.
But actually, I could remove the state dependency by suspending the first step's content in the page.tsx, waiting for the step1 component to fetch it's data. then if the data comes in and says to skip to step 2, the step 1 component will return suspended step 2 component instead of the login form, and so on
maybe thats what you meant tho
I think it's the best idea though as there are not that many steps, otherwise or if there was a dynamic amount of steps I suppose one would have to deal with client side fetching, altough not ideal ofc, or fetch all the data first without any suspending, also not ideal depending on the situation...
Just seems like a tough situation overall with no good general solution, even though I imagine having a child that is dependent on the parents state and that also wants to fetch data must be quite common... strange
But actually, I could remove the state dependency by suspending the first step's content in the page.tsx, waiting for the step1 component to fetch it's data. then if the data comes in and says to skip to step 2, the step 1 component will return suspended step 2 component instead of the login form, and so on
maybe thats what you meant tho
I think it's the best idea though as there are not that many steps, otherwise or if there was a dynamic amount of steps I suppose one would have to deal with client side fetching, altough not ideal ofc, or fetch all the data first without any suspending, also not ideal depending on the situation...
Just seems like a tough situation overall with no good general solution, even though I imagine having a child that is dependent on the parents state and that also wants to fetch data must be quite common... strange
sry for paragraph
@Dutch the only issue is that ideally, is want to have the content part in a <Suspense>, which I cant do if I am waiting to fetch the data before I display the page^.
But actually, I could remove the state dependency by suspending the first step's content in the page.tsx, waiting for the step1 component to fetch it's data. then if the data comes in and says to skip to step 2, the step 1 component will return suspended step 2 component instead of the login form, and so on
maybe thats what you meant tho
I think it's the best idea though as there are not that many steps, otherwise or if there was a dynamic amount of steps I suppose one would have to deal with client side fetching, altough not ideal ofc, or fetch all the data first without any suspending, also not ideal depending on the situation...
Just seems like a tough situation overall with no good general solution, even though I imagine having a child that is dependent on the parents state and that also wants to fetch data must be quite common... strange
the only issue is that ideally, is want to have the content part in a <Suspense>, which I cant do if I am waiting to fetch the data before I display the page^.you can, using the
loading.tsx. It will wrap your whole page content inside a suspense boundarythe step 1 component will return suspended step 2 component instead of the login form, and so onThat sounds a bit complicated for me. That's why I would fetch everything first and then it's already loaded on the clientside. So there wouldn't be any need for loading states. Maybe you want to save each step, but then the current step would show a loading animation (or button) and not the next step content.
DutchOP
I didnt mean for the step to show the next step content, but to show a loading while it loads the data to check if the step even needs to be done, else go directly display the next one
I just think that it would be better for user experience to see the first step be loading for a moment, then immediately complete, then see the next one load and complete, until it arrives at a step that needs to be filled out/completed
I just think that it would be better for user experience to see the first step be loading for a moment, then immediately complete, then see the next one load and complete, until it arrives at a step that needs to be filled out/completed
would be less complicated to just load everything you're right, but its not that much more complicated and I think its the only way to do the fetching serverside for security and also advance through the steps in 1 url
@Dutch I didnt mean for the step to show the next step content, but to show a loading while it loads the data to check if the step even needs to be done, else go directly display the next one
I just think that it would be better for user experience to see the first step be loading for a moment, then immediately complete, then see the next one load and complete, until it arrives at a step that needs to be filled out/completed
yea, you can add inside your
When the server fetches all the data, the user see's the loading state and then the whole client component (stepper) will get the data directly
loading.tsx the first step as loading state. What do you think about it?When the server fetches all the data, the user see's the loading state and then the whole client component (stepper) will get the data directly
DutchOP
but you mean to show the first step loading until all data is fetched, then skip to the first step that needs to be actually done?
@Dutch would be less complicated to just load everything you're right, but its not that much more complicated and I think its the only way to do the fetching serverside for security and also advance through the steps in 1 url
yes, it would be more efficient, less complicated and better UX, because the user can directly see, which steps need to be done and which are already complete
@Dutch but you mean to show the first step loading until all data is fetched, then skip to the first step that needs to be actually done?
yea 👍
You can even put the stepper always on step one, even if it's complete, to display something to the user, that this step is already done. That's just an example. You can do it like you want to handle it
You can even put the stepper always on step one, even if it's complete, to display something to the user, that this step is already done. That's just an example. You can do it like you want to handle it
DutchOP
so you think that showing the user step 1 loading then skipping to lets say step 3 because step 1 and 2 dont need to be done would be better for the user than seeing step 1 loading, then complete, then step 2 the same, then go to step 3?
I'm actually not sure
@Dutch so you think that showing the user step 1 loading then skipping to lets say step 3 because step 1 and 2 dont need to be done would be better for the user than seeing step 1 loading, then complete, then step 2 the same, then go to step 3?
imagine your are the user, would you like to wait until you be able to fill out the specifc step, because the app is showing you a loading state for one step after another?
I wouldn't want to wait. I as the user directly want to see, what I need to do. And I am happy, when I don't need to do so much
I wouldn't want to wait. I as the user directly want to see, what I need to do. And I am happy, when I don't need to do so much
DutchOP
okay but either way the wait time is the same no? wait for all data at once then skip to the step, or load the data for each step one by one and skip forward one step at a time when that data comes in
maybe its a little less if one can combine the data into one query thats true
@Dutch okay but either way the wait time is the same no? wait for all data at once then skip to the step, or load the data for each step one by one and skip forward one step at a time when that data comes in
oh now I am getting your point.. well it's true, that if you fetch only the needed data for step 1, the page will load faster, yes.
But on the other side, if you use serverside fetching, there are no additional calls to your server. There are multiple additional calls to your server (from the client), when the client ask for specific data for each step
But on the other side, if you use serverside fetching, there are no additional calls to your server. There are multiple additional calls to your server (from the client), when the client ask for specific data for each step
DutchOP
well the client wouldnt need to ask for data, the data would be fetched directly from the server and the client component would only get loaded and displayed for the steps which need to be filled out
idk now im confused I think we're just talking past each other but meaning the same thing xd
@Dutch idk now im confused I think we're just talking past each other but meaning the same thing xd
haha yea I think so too. To complete this thread on
How would you solve this?I would solve it like https://nextjs-forum.com/post/1263560870852825169#message-1263561866513481748