Next.js Discord

Discord Forum

Swapping over from svelte

Answered
Oak apple gall wasp posted this in #help-forum
Open in Discord
Oak apple gall waspOP
Hey guys, I have a question regarding state management.
In svelte you could do something like https://hatebin.com/lmdybyosca (+layout.server.ts) which the load function ran only once in the top level layout. You could then access this data via the page store given by svelte.

I am wondering what the best way to mimic this is. As it stands now my user fills out the login form, presses submit. I send the details to my rust api, it creates a session with a cookie going along with it.

Now I need to figure out how to fetch the /api/users/@me endpoint to get the user info of the user and store that in state using something like zustand.
Answered by Jboncz
'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>
    );
}
View full answer

8 Replies

Im not familiar with svelte, but why not hit the endpoint grab the session and user data and store in a cookie?
or are you talking about on the server side?
@Jboncz Im not familiar with svelte, but why not hit the endpoint grab the session and user data and store in a cookie?
Oak apple gall waspOP
I could store it in a cookie but it’s more so how to load this data in context each time so I can use the data reactively
I’m likely going to need it in a cookie anyway as I will also need the data server side
'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>
    );
}
Answer
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>
    )
}
So first one is the context provider, second one is a generic layout in my secured routes.
Obviously you will have to strip out alot of stuff, I have alot more going on lol