How do I re-render the Layout?
Answered
Bombay-duck posted this in #help-forum
Bombay-duckOP
I've put a topbar in my layout file so that it will appear in every page. I've also made the topbar display different things depending on whether or not the user is logged in (e.g. display username only when logged in). I keep track of whether or not the user is logged in with a cookie.
When the user logs out, I want to remove all of the cookies from the client on the server side, and then re-render the layout/topbar so that it reflects the new cookie value.
Is there any way I can trigger a re-render from the server-side, or some way to run a server action from the client side and then re-render on the client side?
Code:
@/app/logout/page.js
Client side code
@/app/logout/logoutServer.js
Server side code
When the user logs out, I want to remove all of the cookies from the client on the server side, and then re-render the layout/topbar so that it reflects the new cookie value.
Is there any way I can trigger a re-render from the server-side, or some way to run a server action from the client side and then re-render on the client side?
Code:
@/app/logout/page.js
Client side code
'use client'
import { logoutServer } from "./logoutServer";
import { useRouter } from 'next/navigation';
import { useEffect } from 'react';
export default async function Logout() {
'use client'
async function l() {
const router = useRouter()
await logoutServer()
router.replace('/login');
router.refresh();
}
useEffect(l);
return (<>
<div onLoad={l}></div>
</>)
} @/app/logout/logoutServer.js
Server side code
'use server'
import { cookies } from 'next/headers';
export async function logoutServer() {
cookies().delete('username');
cookies().delete('token');
}Answered by Bombay-duck
ive achieved the dynamic topbar goal by using template instead of layout, and then storing the username as a react state
then i used useEffect to update the username state using information from the server every componenet update
then i used useEffect to update the username state using information from the server every componenet update
4 Replies
Bombay-duckOP
@/app/layout.js
Uses the Topbar component, see below
@/lib/ui/Topbar/Topbar
Layout just passes username as a prop to Topbar component
Uses the Topbar component, see below
import Topbar from '@/lib/ui/Topbar/Topbar';
import { getUserIdFromToken, getUsername } from '@/lib/helper';
import { Open_Sans } from 'next/font/google';
import '@/lib/ui/baconerie/styles/global.css';
const openSans = Open_Sans({
weight: '500',
subsets: ['latin']
});
export default async function RootLayout({ children }) {
const userId = await getUserIdFromToken(); // Server action that gets id from cookie on server side
const username = await getUsername(); // Server action that gets username from cookie on server side
return (
<html lang='en'>
<body className={openSans.className}>
<Topbar username={userId ? username : null} />
{children}
</body>
</html>
);
}@/lib/ui/Topbar/Topbar
Layout just passes username as a prop to Topbar component
import Link from 'next/link'
import topbarStyles from './Topbar.module.css';
export default function Topbar({ username }) {
let buttons;
if (username) {
buttons = (<>
<b><div className={'wrapper'}>{username}</div></b>
<Link href={'/logout'}>Logout</Link>
</>)
} else {
buttons = (<>
<Link href={'/login'}>Login</Link>
<Link href={'/signup'}>Signup</Link>
</>)
}
return (<div id={topbarStyles.topbarDiv}>
<Link id={topbarStyles.indexLink} href="/"><h1>Header</h1></Link>
<div id={topbarStyles.topbarButtonWrapper} className={'wrapper'}>
{buttons}
</div>
</div>);
}So you want the top bar's content to change when the login state changes?
I'd suggest you to make a client component out of it and passing it params fetched from server, cause reloading isn't a good solution... Another way to do the same is to create a different route, let's say dashboard/ and redirect the user there if he is authenticated... And have a different layout there, you can achieve this easily with a middleware
Bombay-duckOP
ive achieved the dynamic topbar goal by using template instead of layout, and then storing the username as a react state
then i used useEffect to update the username state using information from the server every componenet update
then i used useEffect to update the username state using information from the server every componenet update
Answer