Search code examples
javascriptreactjsreact-context

How to stay logged in when page refreshes with React?


I have a react app for the frontend and I am using django for the backend and I can login. But after page refresh user will be logged out. So I try it like:

authservice:

export const loginRequest = async (email, password) => {
    try {
        const response = await fetch(`${API_URL}/api/user/token/`, {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
            },
            body: JSON.stringify({
                email: email,
                password: password,
            }),
        });

        const data = await response.json();

        if (response.ok) {
            await AsyncStorage.setItem("Token", data.token);

            return true;
        } else {
            throw new Error(data.token);
        }
    } catch (error) {
        error, "email en of wachtwoord is niet goed ingevuld";
    }
};

authcontext:

import {    
    loginRequest
    
} from "./authentication.service";
import React, { createContext, useEffect, useState } from "react";

export const AuthContextProvider = ({ children }) => {
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState(null);
    const [user, setUser] = useState(null);

useEffect(() => {
        const onLogin = (email, password) => {
            setIsLoading(true);
            loginRequest(email, password)
                .then((u) => {
                    setUser(u);                 
                    setIsLoading(false);
                })
                .catch((e) => {
                    setIsLoading(false);                    
                    setError(e.toString());
                });
        };
        onLogin();

    }, []);

    return (
        <AuthContext.Provider
            value={{
                isAuthenticated: !!user,
                isLoading,
                error,
                user,
                loginRequest                
            }}>
            {children}
        </AuthContext.Provider>
    );
};

I call the onLogin function from the component LoginScreen:

const { onLogin, error, isLoading } = useContext(AuthContext);
<Spacer size="large">
                    {!isLoading ? (
                        <AuthButton
                            icon="lock-open-outline"
                            mode="contained"
                            onPress={() => onLogin(email, password)}>
                            Login
                        </AuthButton>
                    ) : (
                        <ActivityIndicator animating={false} />
                    )}
                </Spacer>

But I get this error:

login.screen.js:61  Uncaught TypeError: onLogin is not a function

Question: how to stay loggedin with page refresh?


Solution

  • Regarding the problem of a user getting logged out on page refresh. you can simply fix it in the following way.

    in your authcontext

    import {    
        loginRequest
        
    } from "./authentication.service";
    import React, { createContext, useEffect, useState } from "react";
    
    export const AuthContextProvider = ({ children }) => {
        const [isLoading, setIsLoading] = useState(false);
        
        const [token, setToken] = useState(AsyncStorage.getItem("Token")); 
    
        const [error, setError] = useState(null);
        const [user, setUser] = useState( !!token );
    
    useEffect(() => {
            const onLogin = (email, password) => {
                setIsLoading(true);
                loginRequest(email, password)
                    .then((u) => {
                        setUser(u);                 
                        // assuming token will be comming `u.token` in response
                        setToken(u.token)
                        setIsLoading(false);
                    })
                    .catch((e) => {
                        setIsLoading(false);                    
                        setError(e.toString());
                    });
            };
            onLogin();
    
        }, []);
    
        return (
            <AuthContext.Provider
                value={{
                    isAuthenticated: !!user,
                    isLoading,
                    error,
                    user,
                    loginRequest                
                }}>
                {children}
            </AuthContext.Provider>
        );
    };