refresh client component after server action
Unanswered
Whiteleg shrimp posted this in #help-forum
Whiteleg shrimpOP
Hey! I'm getting the hang of Next.js, but I'm still pretty new. I have a working login server action that redirects to my /dashboard page. However, the navbar in the root layout is a client component and does not update when using revalidatePath('/'). Is there any way I can force my navbar (client component) in the root layout to re-render after this server action?
if i refresh the page manually the navbar ofc works as expected.
//in server action on successfull login
revalidatePath('/')
redirect('/dashboard');if i refresh the page manually the navbar ofc works as expected.
137 Replies
Try give revalidatePath('/', 'layout') a go
https://nextjs.org/docs/app/api-reference/functions/revalidatePath
https://nextjs.org/docs/app/api-reference/functions/revalidatePath
@Velo Try give revalidatePath('/', 'layout') a go
https://nextjs.org/docs/app/api-reference/functions/revalidatePath
Whiteleg shrimpOP
unfortunately i tried this already
@Whiteleg shrimp Hey! I'm getting the hang of Next.js, but I'm still pretty new. I have a working login server action that redirects to my /dashboard page. However, the navbar in the root layout is a client component and does not update when using revalidatePath('/'). Is there any way I can force my navbar (client component) in the root layout to re-render after this server action?
ts
//in server action on successfull login
revalidatePath('/')
redirect('/dashboard');
if i refresh the page manually the navbar ofc works as expected.
revalidatePath doesnt rerender components but instead refreshes serverside cache
so if ur client component doesnt rely on serverside data nothing will change
Whiteleg shrimpOP
mm the navbar does use the next-auth session data
import {useSession} from "next-auth/react";
export default function NavBar() {
const {data: session} = useSession();Whiteleg shrimpOP
yea
so yeah
that will not work
Whiteleg shrimpOP
yea i noticed xD
thats my problem
Whiteleg shrimpOP
well if i change the navbar to server comp, it works, but then all the pages becomes dynamic
Whiteleg shrimpOP
well if the navbar is a server comp, and i make it use the server session function instead, it works with the revalidate, but all pages become dynamic now due to me using session data in the navbar, and the navbar is used on all pages
so next makes all pages dynamic now
instead of having a mix of static and dynamic
so thats why i want the navbar to be a client componet, so things like the home/login/register can stay static, i just need to find a way to refresh the navbar after a server action
specially the login ofc, but in the future things like profile edits aswel
wdym by static tho?
i dont get it
Whiteleg shrimpOP
the page rendering
static pages, dynamic pages
but what difference does it make for u
cause all my pages are dynamic aswell
Whiteleg shrimpOP
i rather do it properly
@Whiteleg shrimp i rather do it properly
i come back to that later
Whiteleg shrimpOP
hehe
i hope your navbar is defined in the layout
right?
Whiteleg shrimpOP
it is
who told u that your approach is "properly"
cause nextjs is a fullstack framework
ofc it renders things on the server when needed
and what difference does it make for u now
do u see some errors or something?
Whiteleg shrimpOP
well if i can keep pages static that are static that would be great, i mean it's a feature nextjs offers so i do want to try and use it. i'm also still learning, i'm only looking for a way to re-render a client component after a server action.
it's not about if it bothers me i'm trying to learn how to do this
@Whiteleg shrimp well if i can keep pages static that are static that would be great, i mean it's a feature nextjs offers so i do want to try and use it. i'm also still learning, i'm only looking for a way to re-render a client component after a server action.
well u have the answer above. ur navbar wrapper is a server component and u have clientside child components who are for your functionality
the nice thing about nextjs is that u can pass serverside data to your child clientside components
that will change if u trigger revalidatePath
Whiteleg shrimpOP
look this was the answer or clue i needed
thanks i will try that
thanks
i can indeed try to pass session data to my navbar in that case
but i need to keep it client side though
but i wil try that in a bit
@Whiteleg shrimp i can indeed try to pass session data to my navbar in that case
yeah and if ur navbar is in the layout it will not rerender when switchtig routes so that is a good approach
Whiteleg shrimpOP
nah doesn't work sadly, makes sense cuss not the root layout is ussing session, meaning no page can be really static, nah the navbar really has to fetch it's own session data so i need to find a way to refresh the navbar after an action
repo or something ill try to fix it
Whiteleg shrimpOP
sure 1 sec
https://github.com/AVMG20/ctrlpanel/tree/master
http://localhost:3000/auth/login for login page, you can type anything random there is no DB yet, just some validation
you get redirected to /dashboard on login
src/app/auth/login/actions.tsx is the login actionhttp://localhost:3000/auth/login for login page, you can type anything random there is no DB yet, just some validation
you get redirected to /dashboard on login
@Whiteleg shrimp do u have something set in your auth panel?
Whiteleg shrimpOP
no but this is an next-auth thingy, i run it locally on localhost:3000, but when i build the app it also works fine
i have not hardcoded localhost:3000
not entirely sure since my production build also runs behind a proxy and works fine
yeah thats weird
maybe its because of codespaces
Whiteleg shrimpOP
I mean, it's fine if it doesn't work out. Another thing I can do is duplicate the navbar for the logged-in bit and have two separate navbars, or partially different ones. That would work as well, but I figured it wasn't going to be such a headache to refresh a client component after a server action.
but it seems it's quite difficult, also cannot find anything online either
thats why i landed here
wait let me clone it on localhost
yeah that worked wait
Whiteleg shrimpOP
okay, nice
@Whiteleg shrimp so whats the issue exactly?
Whiteleg shrimpOP
😂
if you login, you can use any random values
the navbar should re-render aswel
the navbar is a client component, the login is a server action
if you would manually refresh the page after the login it works fine
i see
import Link from "next/link";
import {useSession} from "next-auth/react";
import { auth } from "@/auth";
export default async function NavBar() {
const session = await auth();
return (
<div className="navbar border-b border-base-200">
<div className="flex-1">
<Link href={'/'} className="btn btn-ghost text-xl">CtrlPanel</Link>
</div>
<div className="flex-none">
<Link href={'/store'} className="btn btn-ghost">Store</Link>
{/* No session found */}
{!session && (
<>
<Link href={'/auth/login'} className="btn btn-ghost">Login</Link>
<Link href={'/auth/register'} className="btn btn-ghost">Register</Link>
</>
)}
{/* Session found */}
{session && (
<>
<Link href={'/dashboard'} className="btn btn-ghost">Dashboard</Link>
<Link href={'/profile'} className="btn btn-ghost">Profile</Link>
<Link href={'/api/auth/signout?callbackUrl=/'} className="btn btn-ghost">Sign Out</Link>
</>
)}
</div>
</div>
)
}Whiteleg shrimpOP
having all pages dynamic is not a big deal for this app, but i mean having pages that are static stay static would be nice ofc
copy paste this
Whiteleg shrimpOP
yea no if you build that
i just got that xD
you get all pages dynamic
it does work yes
ok nice
so its fixed
Whiteleg shrimpOP
no not really
it's not urgent but like i said, i figured it wasn't that difficult to force a re-render to a client comp, but appearently it's very difficulyt
bro
u cant force a rerender with revalidatePath
Whiteleg shrimpOP
i know
u can force a rerender using useEffect and checking for param change if u pass that from parent
and have the param in a useState
Whiteleg shrimpOP
haha i did that trick aswel just now
that mighnt work, the auth is fetched using a hook so it was wierd, but i stopped trieng once you said you got it running hasha
i'm gone see if thats an option
yea if all pages are dynamic it does not make them static at al, i just put some random number gen on the static home page and each refresh makes a new number, hence why i would love to be able to use static and have a changing navbar hehe
yeah ofc it generates a new number when u reload the page
Whiteleg shrimpOP
yea
so whats the issue
Whiteleg shrimpOP
it's not static
nextjs is a dynamic framework
Whiteleg shrimpOP
bro plz stop
if u want to have static pages u should go with react
Whiteleg shrimpOP
i already explained it
no lol
nextjs is the framework for static server side rendered pages
react is only front-end rendered
it litterly has static pages in the build process
i want to use it 🙂
i'm gone just make 2 navbars instead and call it unresolved problem
ur navbar is dynamic i still dont get what you tryng to achieve? u cant have your navbar static and also use the features of serverside rendering
Whiteleg shrimpOP
yea hence my navbar is client side
but the whole page is static
when the navbar loads it fetched the data with a extra fetch call
making the navbar dynamic but the rest of the whole page can stay static and the page can be served staticly
this is litterly the main selling point of nextjs
server side rendered applications, improving SEO
etc etc
but i don't want to keep on argueing why i want to do it, i just want to do this 🤷♂️ and find a good solution
and like i said, no good solution is found so i just dupe my navbar for back/end and front/end and call it a day 🙂
thanks for your help
@Whiteleg shrimp but i don't want to keep on argueing why i want to do it, i just want to do this 🤷♂️ and find a good solution
im not arguing with u i just told u idk multiple times that ur initial question is solved right? if the one solution u dont want to use doesnt fit u then i think u could also try it using some type of user context and wrapping that in your layout
and for revalidatePath u can return a 200 from your auth call and update the state that way
Whiteleg shrimpOP
no my initial question is unsolved, the whole premises of the problem is how to force a client component to re-render after a server action
yea i'm gone try and look for some way or just dupe the navbars it's fine
thanks
@Whiteleg shrimp no my initial question is unsolved, the whole premises of the problem is how to force a client component to re-render after a server action
Smalandstövare
hi, i know it has been a long time, did you manage to find a solution to this?
i'm currently looking for a solution to this 😅
@Smalandstövare hi, i know it has been a long time, did you manage to find a solution to this?
Whiteleg shrimpOP
hey hey been a long time, i think i found how i fixed it
const { update } = useSession()
const [state, action] = useFormState<BaseFormState, FormData>(editProfile, {});
//we need this to update the session data.
useEffect(() => {
if (state.success) {
update({username: 'username'}).then(async data => {
await revalidateProfilePage()
})
}
}, [state])I basically hooked into the formState and if the edit was successful, I updated my client session data to re-render the navbar (which is a client component).
hope this helps 🙂
Smalandstövare
thank you! ill test it now