Search code examples
reactjsauthenticationlocal-storageuse-effectreact-context

Best way to check if there is already a token in local storage using use effect in React Context


good day. Is this the best way to check if there is already a token in my local storage in my AuthContext? I used a useEffect hook in checking if the token already exists. Should I change the initial state of isAuthenticated since it is always false upon rendering? Im not sure. Thank you

import React, { useState, useContext, useEffect } from "react";

const AuthContext = React.createContext();

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

export const AuthProvider = ({ children }) => {
    const [isAuthenticated, setAuthenticated] = useState(false);

    const login = () => {
        setAuthenticated(true);
    };

    useEffect(() => {
        const token = localStorage.getItem("AuthToken");
        if (token) {
            setAuthenticated(true);
        } else if (token === null) {
            setAuthenticated(false);
        }

        return () => {};
    }, []);

    return <AuthContext.Provider value={{ isAuthenticated, login }}>{children}</AuthContext.Provider>;
};


Solution

  • I would suggest using a state initializer function so you have correct initial state. You won't need to wait until a subsequent render cycle to have the correct authentication state.

    const [isAuthenticated, setAuthenticated] = useState(() => {
      const token = localStorage.getItem("AuthToken");
      return token !== null;
    });
    

    The rest can likely remain the same.

    I suggest you also provide a default context value as well.

    const AuthContext = React.createContext({
      isAuthenticated: false,
      login: () => {},
    });
    
    export function useAuth() {
      return useContext(AuthContext);
    }
    
    export const AuthProvider = ({ children }) => {
      const [isAuthenticated, setAuthenticated] = useState(() => {
        const token = localStorage.getItem("AuthToken");
        return token !== null;
      });
    
      const login = () => setAuthenticated(true);
      
      return (
        <AuthContext.Provider value={{ isAuthenticated, login }}>
          {children}
        </AuthContext.Provider>
      );
    };