Next.js Discord

Discord Forum

Refreshing a layout component from a page

Unanswered
Masai Lion posted this in #help-forum
Open in Discord
Masai LionOP
I have a component in layout.js that I want to update when I do something in a page (eg. /accounts). How can I do this?

3 Replies

You would use a context provider to expose it. Lemme grab an example real quick
Layout
import { NavigationBar, Navigation, Profile, Title } from "@/components/Navigation";
import { NavigationProvider } from "@/components/providers/NavigationProvider";
import { ReauthProvider } from "@/components/providers/ReAuthProvider";
import { cookies } from "next/headers";

export default function RootLayout({ children }) {
    let navCookie = cookies().get(process.env.NavCookieName);
    if (navCookie) {
        navCookie = JSON.parse(navCookie.value);
    }

    return (
        <div>
            <ReauthProvider>
                <NavigationProvider profile={navCookie || null}>
                    <NavigationBar left={<Navigation />} center={<Title />} right={<Profile />} />
                    <div>
                        {children}
                    </div>
                </NavigationProvider>
            </ReauthProvider>
        </div>
    )
}


Navigation Provider
'use client';
import { createContext, useState, useContext, useEffect } from 'react';

const NavigationContext = createContext({
    pageTitle: null,
    setPageTitle: () => { },
    drawerOpen: false,
    toggleDrawer: () => { },
    userProfile: null,
    setUserProfile: () => { },
    loading: true, // Add a loading state
});

export function useNavigation() {
    return useContext(NavigationContext);
}

export function NavigationProvider({ children, profile }) {
    const [userProfile, setUserProfile] = useState(profile);
    const [pageTitle, setPageTitle] = useState(null);
    const [drawerOpen, setDrawerOpen] = useState(false);
    const [loading, setLoading] = useState(true);

    useEffect(() => {
        setUserProfile(profile);
        setLoading(false);
    }, [profile]);

    const toggleDrawer = () => {
        setDrawerOpen(!drawerOpen);
    };

    const value = {
        pageTitle,
        setPageTitle,
        drawerOpen,
        toggleDrawer,
        userProfile,
        setUserProfile,
        loading,
    };

    return (
        <NavigationContext.Provider value={value}>
            {!loading && children}
        </NavigationContext.Provider>
    );
}


Using inside my navigation bar
import { useNavigation } from '@/components/providers/NavigationProvider';

const { pageTitle, setPageTitle, drawerOpen, toggleDrawer, userProfile } = useNavigation();


now I can access the functions I exposed from the provider from any client component.
Masai LionOP
ty