Within my Next.js application, I am seeking a way to verify whether a user has permission to access a particular page. While using a context, I encountered an issue where my useEffect hook was returning both the updated and default values. How can I ensure only the most recent value is returned?
Here is the guard page I have implemented:
"use client";
import React, { createContext, useState, useEffect} from "react";
import { tokenServices } from "./services";
import { usePathname } from "next/navigation";
type JWTContextType = {
isAuthenticated: boolean;
};
const AuthContext = createContext<JWTContextType>({
isAuthenticated: false,
});
const AuthProvider = ({ children }: { children: React.ReactNode }) => {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const hasAccess = tokenServices.getToken();
const pathname = usePathname();
useEffect(() => {
if (hasAccess) {
setIsAuthenticated(true);
} else if (!hasAccess) {
setIsAuthenticated(false);
}
}, [pathname, hasAccess]);
return (
<AuthContext.Provider value={{ isAuthenticated }}>
<>{children}</>
</AuthContext.Provider>
);
};
export { AuthContext, AuthProvider };
Here is the layout page I am using:
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { AuthProvider } from "./GuestGuard";
import { ProtectedRoutes } from "./protectedRoutes";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Next App",
description: "Generated by create next app",
manifest: "/manifest.json",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<AuthProvider>
<ProtectedRoutes>
<body className={inter.className}>{children}</body>
</ProtectedRoutes>
</AuthProvider>
</html>
);
}
My expectation is that the useEffect hook should only return a single value.