useNavigate redirecting but not loading - javascript

the URL shows that it is login page but everything is white, and when I reload it loads the page.
in the console says that many variables from the previous page are null, it seems like it's still on the previous page. why is this happening?
The previous page and the code:
import React, { useState } from 'react'
import { useNavigate } from 'react-router-dom'
import '../styles/UserProfile.css'
import { useAuth } from '../services/authContext'
export default function UserProfile() {
const { currentUser, logout } = useAuth()
const navigate = useNavigate()
const [errorMessage, setErrorMessage] = useState(null)
async function handleLogout() {
try {
await logout()
navigate("/login")
} catch (error) {
console.log(error)
setErrorMessage('An error ocurred when trying to logout')
}
}
return (
<div className="container profile">
<div className="profile">
<h1>Profile</h1>
{errorMessage && (
<div className="error-container">
<strong>{errorMessage}</strong>
</div>
)}
<div className="row">
<h3>Email</h3>
<p>{currentUser.email}</p>
</div>
<div className="row">
<a>Change email</a>
</div>
<div className="row">
<a>Reset password</a>
</div>
<button onClick={handleLogout}>Logout</button>
</div>
</div>
)
}
and when i click logout this happens:
when i reload it loads normally
useAuth code:
import React, { createContext, useContext, useEffect, useState } from 'react'
import {
createUserWithEmailAndPassword,
onAuthStateChanged,
signInWithEmailAndPassword,
signOut,
} from 'firebase/auth'
import { auth } from '../firebase'
const AuthContext = createContext()
export function useAuth() {
return useContext(AuthContext)
}
export function AuthProvider({ children }) {
const [currentUser, setCurrentUser] = useState()
function signUp(email, password) {
return createUserWithEmailAndPassword(auth, email, password)
}
function login(email, password) {
return signInWithEmailAndPassword(auth, email, password)
}
function logout() {
return signOut(auth)
}
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, user => {
setCurrentUser(user)
})
return unsubscribe
}, [])
return (
<AuthContext.Provider
value={{
signUp: signUp,
login: login,
logout: logout,
currentUser: currentUser,
}}
>
{children}
</AuthContext.Provider>
)
}
login code:
import React, { useState } from 'react'
import { useAuth } from '../services/authContext'
import { useNavigate, Link } from 'react-router-dom'
import Header from '../components/Header'
export default function Login() {
const { login } = useAuth()
const navigate = useNavigate()
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [loading, setLoading] = useState(false)
const [errorMessage, setErrorMessage] = useState(null)
async function handleSubmit(element) {
element.preventDefault()
setLoading(true)
if (password.length < 6) {
setErrorMessage('The password need to have at least 6 characters!')
setLoading(false)
return
}
try {
await login(email, password)
navigate('/')
} catch (error) {
setErrorMessage('An error occured when trying to login')
}
setLoading(false)
}
return (
<div className="container">
<Header />
<h2>Login</h2>
{errorMessage && (
<div className="error-container">
<strong>{errorMessage}</strong>
</div>
)}
<form onSubmit={handleSubmit}>
<label>Email</label>
<input
type="email"
value={email}
onChange={e => setEmail(e.target.value)}
/>
<label>Password</label>
<input
type="password"
value={password}
onChange={e => {
setPassword(e.target.value)
}}
/>
<button disabled={loading} className="button-block" type="submit1">
Login
</button>
</form>
<div className="center">
<p>
ForgotPassword ? <Link to="/forgot-password">Reset password</Link>
</p>
<p>
Don't have an account ? <Link to="/signup">Create account</Link>
</p>
</div>
</div>
)
}
i consoled log currentUser and currentUser.email before logout, and it's not null, this happens after logging out.

UserProfile.jsx:32:1 is <p>{currentUser.email}</p>. As far as I can tell it appears the currentUser object is nullified and the UserProfile component is rerendered at least once prior to the navigation action being effected to navigate the user to the "/login" path. The UserProfile component falls over when attempting to access currentUser.email when currentUser is null.
You should place a guard on the UI to only render valid content when currentUser is non-null.
Example:
export default function UserProfile() {
const { currentUser, logout } = useAuth();
const navigate = useNavigate();
const [errorMessage, setErrorMessage] = useState(null);
async function handleLogout() {
try {
await logout();
navigate("/login");
} catch (error) {
console.log(error);
setErrorMessage('An error ocurred when trying to logout');
}
}
if (!currentUser) {
return <div>No Current user. Log in.</div>;
}
return (
<div className="container profile">
<div className="profile">
<h1>Profile</h1>
{errorMessage && (
<div className="error-container">
<strong>{errorMessage}</strong>
</div>
)}
<div className="row">
<h3>Email</h3>
<p>{currentUser.email}</p>
</div>
<div className="row">
<a>Change email</a>
</div>
<div className="row">
<a>Reset password</a>
</div>
<button onClick={handleLogout}>Logout</button>
</div>
</div>
)
}

Related

react doesn't update the data, only after reloading page

It is my Auth Login form. I have AuthContext. Let's try log in.
I've clicked "log in" button. And we see AuthContext "user" : underfind
Then click reload page, and here we go, we have logged in
Why does it work like that?
Login.js
import React, {useState} from 'react'
import {useLogin} from '../hooks/useLogin'
import { useNavigate } from 'react-router-dom'
const Login = () => {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const {login, error, isLoading} = useLogin()
let navigate = useNavigate()
const handleSubmit = async (e) => {
e.preventDefault()
await login(email, password)
}
return(
<div className='container'>
<h1>
login page
</h1>
<form className={'d-flex flex-column'} onSubmit={handleSubmit}>
<h3>Log in</h3>
<label>Email:</label>
<input
type={'email'}
onChange={(e) => setEmail(e.target.value)}
/>
<label>Password</label>
<input
type={'password'}
onChange={(e) => setPassword(e.target.value)}
/>
<button disabled={isLoading} type={'submit'}>
Log in
</button>
{error && <div className={'error'}>
{error}
</div>}
</form>
</div>
)
}
export default Login;
useLogin.js
import { useState } from "react";
import { useAuthContext } from "./useAuthContext";
export const useLogin = () => {
const [error, setError] = useState(null)
const [isLoading, setIsLoading] = useState(null)
const {dispatch} = useAuthContext()
const login = async (email, password) => {
setIsLoading(true)
setError(null)
const response = await fetch('/api/user/login', {
method:'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({email, password})
})
const json = await response.json()
if(!response.ok){
setIsLoading(false)
setError(json.error)
}
if(response.ok){
localStorage.setItem('user', JSON.stringify(json))
dispatch({type:'LOGIN', paylaod:json})
setIsLoading(false)
}
}
return {login, isLoading, error}
}
AuthContext.js
import { createContext, useReducer, useEffect } from "react";
export const AuthContext = createContext()
export const authReducer = (state, action) => {
switch(action.type){
case 'LOGIN':
return {user: action.payload}
case 'LOGOUT':
return {user:null}
default:
return state
}
}
export const AuthContextProvider = ({children}) => {
const [state, dispatch] = useReducer(authReducer, {
user:null
})
useEffect(() => {
const user = JSON.parse(localStorage.getItem('user'))
if(user){
dispatch({type:'LOGIN', payload: user})
}
}, [])
console.log('AuthContext state', state)
return(
<AuthContext.Provider value={{...state, dispatch}}>
{children}
</AuthContext.Provider>
)
}
useAuthContext.js
import { AuthContext } from "../context/AuthContext";
import { useContext } from "react";
export const useAuthContext = () => {
const context = useContext(AuthContext)
if(!context){
throw Error('useAuthContext must be used inside an AuthContextProvider')
}
return context
}
here is Navbar.js
import React from "react";
import { useAuthContext } from "../hooks/useAuthContext";
import { useLogout } from "../hooks/useLogout";
import { Link } from "react-router-dom";
const Nav = () => {
const {logout} = useLogout()
const {user} = useAuthContext()
const handleClick= () => {
logout()
}
return(
<div>
{user && (
<div className="bg-dark text-light align-item-center d-flex justify-content-between m-auto container-fluid p-2">
<span className="m-0 p-0 d-flex align-item-center">{user.email}</span>
<button className="btn btn-outline-danger" onClick={handleClick}>logout</button>
</div>
)}
{!user && (
<div className="d-flex justify-content-between">
<Link to='/'>
<button>HOME</button>
</Link>
<Link to='/login'>
<button>LOGIN</button>
</Link>
<Link to='/signup'>
<button>SIGNUP</button>
</Link>
</div>
)}
</div>
)
}
export default Nav
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { AuthContextProvider } from './context/AuthContext';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<AuthContextProvider>
<App />
</AuthContextProvider>
</React.StrictMode>
);
app.js
import {BrowserRouter, Routes, Route} from 'react-router-dom'
import Nav from './components/Nav';
import Home from './pages/home';
import Login from './pages/login';
import Signup from './pages/signup';
function App() {
return (
<div>
<BrowserRouter>
<Nav/>
<Routes>
<Route path={'/'} element={<Home/>}/>
<Route path={'/login'} element={<Login/>}/>
<Route path={'/signup'} element={<Signup/>}/>
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
I don't think it is server error.
There's a spelling mistake in useLogin payload is written wrong
dispatch({type:'LOGIN', paylaod:json});
// Should be: Payload
dispatch({type:'LOGIN', payload:json});
The root cause seems to be a typo:
dispatch({type:'LOGIN', paylaod:json})
has a typo in paylaod, so the reducer's
case 'LOGIN':
return {user: action.payload}
basically just sets {user: undefined}.
You should add error checking to your reducer, or better yet switch to a typed language like TypeScript so typos like these are caught at type-check time.
Since the user is not in the component state, it will not re-render after it is set (which seems to happen after first rendering). Add a useEffect with dependency on the value that updates the state and it should be good. F.ex:
const Nav = () => {
const {contextUser} = useAuthContext()
const [user, setUser] = useState()
...
useEffect(() => {
if (contextUser) {
setUser(contextUser)
}
}, [contextUser])
...
}

nextjs firebaseauth redirect before render page if logged in

I have a login page and an auth provider as follow
import * as yup from "yup";
import { useState } from 'react'
import { AuthErrorCodes } from 'firebase/auth'
import Cover from '../../components/Cover'
import Head from 'next/head'
import Headingblock from '../../components/Headingblock'
import Section from '../../components/Section'
import { authErrorCodesTranslation } from '../../config/firebase';
import { siteTitle } from '../_app'
import { useForm } from 'react-hook-form';
import { yupResolver } from '#hookform/resolvers/yup';
import { useRouter } from 'next/router';
import { useAuth } from "../../contexts/auth";
import { auth } from '../../config/firebase';
import { signInWithEmailAndPassword } from "firebase/auth";
import {useEffect} from 'react'
export default function Login() {
const [response, setResponse] = useState({});
const [user, userLoading] = useAuth();
const router = useRouter();
console.log(userLoading);
if (!userLoading && user)
router.push('/');
const schema = yup.object().shape({
email: yup.string().email('Adresse email invalide').required('Veuillez renseigner votre adresse email.'),
password: yup.string().required('Veuillez renseigner votre mot de passe')
});
const { register, handleSubmit, formState } = useForm({
resolver: yupResolver(schema),
});
const { errors } = formState;
const onSubmit = async (data) => {
await signInWithEmailAndPassword(auth, data.email, data.password)
.then(userCredential => {
router.push("/profile");
}).catch(error => {
const authErrorCode = Object.keys(AuthErrorCodes).find(k => AuthErrorCodes[k] === error.message);
let errorTranslation = authErrorCodesTranslation.GLOBAL_AUTH_ERROR;
if (authErrorCode !== undefined)
errorTranslation = authErrorCodesTranslation[authErrorCode];
setResponse({ status: 'error', message: errorTranslation });
})
}
return (
<>
<Head>
<title>{siteTitle} - Connexion</title>
</Head>
<Cover />
<Section>
<div className='container marginNTop100'>
<div style={{ padding: '3rem 1.5rem', background: 'white', boxShadow: '0 30px 50px 0 rgb(1 1 1 / 15%)' }}>
<Headingblock main="Connexion" />
<form onSubmit={handleSubmit(onSubmit)}>
<div className="form-row">
<div className="form-group col" style={formgroupStyle}>
<label style={labelStyle}>Adresse email</label>
<input {...register("email")} type="text" className='form-control' style={formcontrolStyle} />
<div className="invalid-feedback" style={invalidStyle}>{errors.email?.message}</div>
</div>
<div className="form-group col" style={formgroupStyle}>
<label style={labelStyle}>Mot de passe</label>
<input {...register("password")} type="password" className='form-control' style={formcontrolStyle} />
<div className="invalid-feedback" style={invalidStyle}>{errors.password?.message}</div>
</div>
</div>
<div className="form-group" style={formgroupStyle}>
<button type="submit" style={Object.assign(btnStyle, btnprimaryStyle)}>
Connexion
</button>
</div>
{
response.status === 'error' && <div style={Object.assign(alertStyle, alertDangerStyle)}>{response.message}</div>
}
</form>
</div>
</div>
</Section>
</>
)
}
import { createContext, useState, useEffect, useContext } from 'react';
import { onAuthStateChanged } from 'firebase/auth';
import { auth } from '../config/firebase'
const AuthContext = createContext({ user: null, userLoading: true });
export const AuthProvider = ({ children }) => {
const [userLoading, setUserLoading] = useState(true);
const [user, setUser] = useState();
useEffect(() => {
return onAuthStateChanged(auth, (user) => {
console.log('autstatechanged');
if (user) {
console.log("1");
setUser(user);
setUserLoading(false);
// ...
} else {
console.log("2");
setUser(null);
}
});
}, []);
return (
<AuthContext.Provider value={[user, userLoading]}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => useContext(AuthContext);
Once user is logged in I would like that page being not available anymore so I made a redirect once user is set and userloading is false but the page is rendering before redirect that causes a blink effect.
I wouldn't like return a loading screen I think It should be possible to not render login page if user is logged in

How do I update my NavBar once a user is logged-in (from 'log in' to 'profile') using React & Firebase?

I'm new to Reactjs & Firebase, but I've managed to set up a signup/login system- now once the user logs in, I have them redirected back to the home page, but I want the nav bar to display 'profile' instead of the original 'log in'. I know this is something to do with Conditional Rendering but I'm having trouble implementing it with Firebase.
NavBar.js
import { Link } from 'react-router-dom'
// import { AuthProvider, useAuth } from '../contexts/AuthContext'
// import firebase from 'firebase/compat/app';
const NavBar = () => {
return (
<header>
<Link to = '/'>
<img src = {require('../images/logo.png')} alt = 'logo'/>
</Link>
<div id = 'nav-pages'>
<Link to='/contact'>contact</Link>
<Link to='/about'>about</Link>
{/* change this to a link to a profile page */}
<Link to='/login'>log-in</Link>
</div>
</header>
)
}
export default NavBar
LogIn.js
import React, { useRef, useState } from 'react'
import NavBar from '../components/NavBar'
import Footer from '../components/Footer'
import { Link, useNavigate } from 'react-router-dom';
import { AuthProvider, useAuth } from '../contexts/AuthContext'
// change to login css
import '../css/SignUp.css'
export default function Login(){
const emailRef = useRef();
const passwordRef = useRef();
const { login } = useAuth();
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const navigate = useNavigate();
async function handleSubmit(e){
e.preventDefault();
try {
setError("");
setLoading(true);
await login(emailRef.current.value, passwordRef.current.value);
navigate('/', {replace: true});
} catch {
setError('failed to sign in');
}
setLoading(false);
}
return (
<>
<NavBar/>
<div id = 'signup'>
<div id = 'card'>
<h2>log in</h2>
{error && <p id = 'error'>{error}</p>}
<form onSubmit={handleSubmit} id='form'>
<form id='email'>
<p>email</p>
<input type='email' ref = {emailRef} required/>
</form>
<form id='password'>
<p>password</p>
<input type='password' ref = {passwordRef} required/>
</form>
<button type='submit' disabled={loading}>log in</button>
</form>
</div>
<p>need an account? <Link to='/signup'>Sign Up</Link></p>
</div>
<Footer/>
</>
)
}
AuthContext.js
import React, { useContext, useState, useEffect } from 'react'
import { auth } from '../firebase';
const AuthContext = React.createContext()
export function useAuth(){
return useContext(AuthContext)
}
export function AuthProvider({ children }){
const [currentUser, setCurrentUser] = useState();
const [loading, setLoading] = useState(true);
function signup(email, password){
return auth.createUserWithEmailAndPassword(email, password)
}
function login(email, password){
return auth.signInWithEmailAndPassword(email,password)
}
useEffect(() => {
const unsubscribe = auth.onAuthStateChanged(user => {
setCurrentUser(user)
setLoading(false)
})
return unsubscribe
}, [])
const value = {
currentUser,
login,
signup,
}
return (
<AuthContext.Provider value={value}>
{!loading && children}
</AuthContext.Provider>
);
}
I think you should be able to do this:
import { Link } from 'react-router-dom'
import { useAuth } from '../contexts/AuthContext'
// import firebase from 'firebase/compat/app';
const NavBar = () => {
let user = useAuth().currentUser;
return (
<header>
<Link to = '/'>
<img src = {require('../images/logo.png')} alt = 'logo'/>
</Link>
<div id = 'nav-pages'>
<Link to='/contact'>contact</Link>
<Link to='/about'>about</Link>
{user && <Link to="/profile" >Profile</Link>}
{!user && <Link to='/login'>log-in</Link>}
</div>
</header>
)
}
export default NavBar
So the line with useAuth().currentUser will get the user from the context / provider.
And the line with { user && <xxx /> } will be rendered when there is a user.
And the line with { !user && <xxx /> } will be rendered when there is no user.

Removing the token from local Storage

So here I have Login functionality via local storage token. I am getting the token upon user being created in The dev tools/Application. It is redirecting me to the home as it should. The thing that is not working is this. When I try to press the logout I am getting ×TypeError: Cannot read property 'push' of undefined it is showing the error in the Logout Handler function
Context Api
import React from "react";
import { useHistory } from "react-router-dom"
const UserContext = React.createContext();
function getUserFromLocalStorage() {
return localStorage.getItem("authToken")
? JSON.parse(localStorage.getItem("authToken"))
: { username: null, token: null };
}
function UserProvider({ children }) {
const [user, setUser] = React.useState(getUserFromLocalStorage());
const history = useHistory()
const logoutHandler = () =>{
localStorage.removeItem("authToken");
setUser(user);
history.push("/")
}
return (
<UserContext.Provider
value={{ user, setUser, logoutHandler }}
>
{children}
</UserContext.Provider>
);
}
export { UserContext, UserProvider };
Login Link
import React from "react";
import { Link } from "react-router-dom";
import { UserContext } from "../../context/user";
import { useHistory } from "react-router-dom"
export default function LoginLink() {
const { user, logoutHandler } = React.useContext(UserContext);
if (user.authToken) {
return (
<button
onClick={() => {
logoutHandler();
}}
className="login-btn"
>
logout
</button>
);
}
return <Link to="/login">login</Link>;
Header
import React from 'react';
import { Link, useHistory } from "react-router-dom";
import Search from './Search';
import './Header.css'
import SearchBooks from './SearchBooks';
import LoginLink from '../Signin/LoginLink';
import CartLink from '../Cart/CartLink';
import { UserContext } from '../../context/user';
const Header = () => {
const { user } = React.useContext(UserContext);
return (
<div className='header__container'>
<Link to='/'>
<img src='/audi.png' />
</Link>
<li>
<LoginLink />
</li>
{user.authToken &&(
<CartLink />
)
}
</div>
)
}
export default Header
Login
import { useState, } from "react";
import { useHistory } from "react-router-dom"
import axios from "axios";
import { Link } from "react-router-dom";
import "./Signin.css";
const Login = () => {
const { user, setUser } = React.useContext(UserContext);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const history = useHistory()
const loginHandler = async (e) => {
e.preventDefault();
const config = {
header: {
"Content-Type": "application/json",
},
};
try {
const { data } = await axios.post(
"http://localhost:5000/api/auth/login",
{ email, password },
config
);
localStorage.setItem("authToken", data.token);
setUser(user)
history.push("/");
} catch (error) {
if (error.response) {
setError(error.response.data.error);
}
setTimeout(() => {
setError("");
}, 5000);
}
};
return (
<div className="login-screen">
<form onSubmit={loginHandler} className="login-screen__form">
<h3 className="login-screen__title">Login</h3>
{error && <span className="error-message">{error}</span>}
<div className="form-group">
<label htmlFor="email">Email:</label>
<input
type="email"
required
id="email"
placeholder="Email address"
onChange={(e) => setEmail(e.target.value)}
value={email}
tabIndex={1}
/>
</div>
<div className="form-group">
<label htmlFor="password">
Password:{" "}
<Link to="/forgotpassword" className="login-screen__forgotpassword">
Forgot Password?
</Link>
</label>
<input
type="password"
required
id="password"
autoComplete="true"
placeholder="Enter password"
onChange={(e) => setPassword(e.target.value)}
value={password}
tabIndex={2}
/>
</div>
<button type="submit" className="btn btn-primary">
Login
</button>
<span className="login-screen__subtext">
Don't have an account? <Link to="/register">Register</Link>
</span>
</form>
</div>
);
};
export default Login;

Logout funcionality via local storage

So here I have Login funcionality via local storage token. I am getting the token upon user being created in The dev tools/Application it is redirecting me to the home that is working. The thing that is not working is this. Creating an user it is working but when it loads it should show logout instead of login, and should hide the cart Component. Where am I making a mistake
Context Api
import React from "react";
const UserContext = React.createContext();
function getUserFromLocalStorage() {
return localStorage.getItem("authToken")
? JSON.parse(localStorage.getItem("authToken"))
: { username: null, token: null };
}
function UserProvider({ children }) {
const [user, setUser] = React.useState(getUserFromLocalStorage());
const history = useHistory();
const logoutHandler = () =>{
localStorage.removeItem("user");
history.push("/")
}
return (
<UserContext.Provider
value={{ user, logoutHandler }}
>
{children}
</UserContext.Provider>
);
}
export { UserContext, UserProvider };
Login Link
import React from "react";
import { Link } from "react-router-dom";
import { UserContext } from "../../context/user";
import { useHistory } from "react-router-dom"
export default function LoginLink() {
const { user, logoutHandler } = React.useContext(UserContext);
if (user.authToken) {
return (
<button
onClick={() => {
logoutHandler();
}}
className="login-btn"
>
logout
</button>
);
}
return <Link to="/login">login</Link>;
}
Header
import React from 'react';
import { Link, useHistory } from "react-router-dom";
import Search from './Search';
import './Header.css'
import SearchBooks from './SearchBooks';
import LoginLink from '../Signin/LoginLink';
import CartLink from '../Cart/CartLink';
import { UserContext } from '../../context/user';
const Header = () => {
const { user } = React.useContext(UserContext);
return (
<div className='header__container'>
<Link to='/'>
<img src='/audi.png' />
</Link>
<li>
<LoginLink />
</li>
{user.authToken &&(
<CartLink />
)
}
</div>
)
}
export default Header
Login Component
import { useState, } from "react";
import { useHistory } from "react-router-dom"
import axios from "axios";
import { Link } from "react-router-dom";
import "./Signin.css";
const Login = () => {
const { user, setUser } = React.useContext(UserContext);
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const history = useHistory()
const loginHandler = async (e) => {
e.preventDefault();
const config = {
header: {
"Content-Type": "application/json",
},
};
try {
const { data } = await axios.post(
"http://localhost:5000/api/auth/login",
{ email, password },
config
);
localStorage.setItem("authToken", data.token);
setUser(user)
history.push("/");
} catch (error) {
if (error.response) {
setError(error.response.data.error);
}
setTimeout(() => {
setError("");
}, 5000);
}
};
return (
<div className="login-screen">
<form onSubmit={loginHandler} className="login-screen__form">
<h3 className="login-screen__title">Login</h3>
{error && <span className="error-message">{error}</span>}
<div className="form-group">
<label htmlFor="email">Email:</label>
<input
type="email"
required
id="email"
placeholder="Email address"
onChange={(e) => setEmail(e.target.value)}
value={email}
tabIndex={1}
/>
</div>
<div className="form-group">
<label htmlFor="password">
Password:{" "}
<Link to="/forgotpassword" className="login-screen__forgotpassword">
Forgot Password?
</Link>
</label>
<input
type="password"
required
id="password"
autoComplete="true"
placeholder="Enter password"
onChange={(e) => setPassword(e.target.value)}
value={password}
tabIndex={2}
/>
</div>
<button type="submit" className="btn btn-primary">
Login
</button>
<span className="login-screen__subtext">
Don't have an account? <Link to="/register">Register</Link>
</span>
</form>
</div>
);
};
export default Login;
After you login, you have only set the authToken into your localStorage and not in your Provider. You'll need to call setUser after you login in order for Header component to know user is logged in.

Categories