Using Next.js (14.1.0) with App directory and no SRC folder.

I want to read cookies in layout.tsx so I can affect various UI components globally if a user is logged in, (ie in the Nav, removing signin button and replacing with user icon).

Upon refreshing the page I'm getting the error:

Server Error
Error: (0 , _context_auth__WEBPACK_IMPORTED_MODULE_4__.useAuthContext) is not a function

This error happened while generating the page. Any console logs will be displayed in the terminal window.

 > 10 | const { setIsLoggedIn } = useAuthContext();                                            
                                               ^

I'm not sure what to make of this error or how to fix it, nor if the way I've implemented it is correct. My setup is:

layout.tsx:

import type { Metadata } from "next";
import { cookies } from 'next/headers';
import { Inter } from "next/font/google";
import "./globals.css";
import Header from "@/components/Header";
import { useAuthContext, AuthContextWrapper } from '@/context/auth';

const inter = Inter({ subsets: ["latin"] });

const { setIsLoggedIn } = useAuthContext();

const c = cookies();
const token = c.get('AuthToken');
setIsLoggedIn(token ? true : false);

export const metadata: Metadata = {
  title: "App",
  description: "App",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={inter.className}>

        <AuthContextWrapper>
          <Header />
          <main className="flex min-h-screen flex-col items-center justify-center">
            {children}
          </main>
        </AuthContextWrapper>
      </body>
    </html>
  );
}

@context/auth/index.tsx

"use client"

import React, { useState, createContext, useContext } from 'react';

const AuthContext = createContext<any>(false);

export function AuthContextWrapper({ children } : {
  children: React.ReactNode;
}) {
  let [isLoggedIn, setIsLoggedIn] = useState(false);

  return (
    <AuthContext.Provider value={{
      isLoggedIn,
      setIsLoggedIn
    }}>
      {children}
    </AuthContext.Provider>
  )
}

export function useAuthContext() {
  return useContext(AuthContext);
}

I'd really like to use context for this and not prop drill the cookie result down into components I need it in. Is my implementation correct and if so, what might be going wrong here?

EDIT: After some reading I think this might be related to the order components render in. @context/auth/index.tsx probably isn't rendered yet when it's first called in layout. If I'm right, advice on how to handle my scenario is appreciated.

0

There are 0 best solutions below