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.