authenticationnext.jsnext.js13app-router

Optimizing User Data Fetching in Next.js: Best Practices and Alternatives


I have a project in Next.js and I am using server actions. However, I am facing a problem: I am fetching user data separately on each page so that I can use it on the respective pages. Is there a way to fetch the user data once and use it across all pages without fetching it on each page?

I understand that one solution might be to use context or tools like **Redux **to fetch the data once and reuse the stored data in other parts. However, I am fetching the data in a server action in a server component, which would then require me to use a client component.

Is there a better way to handle this? Should I consider fetching the data on the client side with some store management, or is there a good alternative?


Solution

  • This is how i solved this problem.

    export default async function RootLayout({ children }: { children: React.ReactNode }) {
    
        const user = await getCurrentUser() // Hitting tRPC endpoint to get user from DB via sessionId in cookie
    
        return (
            <html>
                <head></head>
                <body>
                    <TrpcProvider>
                        <UserProvider defaultUser={user}>
                            {children}
                        </UserProvider>
                    </TrpcProvider>
                </body>
            </html>
        )
    }
    
    
    / UserProvider
    interface UserProviderProps {
        children: React.ReactNode
        defaultUser: Public_User_Me_Payload | null | undefined
    }
    
    export const UserProvider = ({ children, defaultUser }: UserProviderProps) => {
    
        const result = trpc.public.user.me.useQuery(undefined, {
            initialData: defaultUser
        })
    
        const value = {
            user: result.data || defaultUser,
            isLoading: result.isFetching || result.isLoading,
            error: result.error,
            refetch: result.refetch,
        }
    
        return (
            <UserContext.Provider value={value}>
                {children}
            </UserContext.Provider>
        )
    }