I feel like i lose brain cells everytime i use typescript. I am not liking it at all. I am also not getting a single error but it isnt working how it is supposed to. Anyways, i have a Login Component and a Dashboard component. using useContext, i created a user state and setUser function and used context to pass it into the login component. After logging in, I am redirected to the dashboard route. The dashboard route only has a single button that logs me out and removes the current user. The Problem is that everytime i refresh on the dashboard route, it logs me out and redirects me to login, instead of getting the user from localStorage, parsing the value and using setUser. since a user would still be present at this point, it shouldnt redirect me to login. Also, when i change the initial value of user to {} instead of null, then it doesnt log me out on a refresh but the dashboard route becomes unprotected and i can visit it even though a user is not present. What am i doing wrong, the code seems like it should be working.
export type UserProps = {
user: {
name?: string,
token?: string
} | null,
setUser: React.Dispatch<React.SetStateAction<{} | null>>
}
UserContext.tsx:
import {createContext, useEffect, useState} from 'react'
import { UserProps } from './types'
export const UserContext = createContext<UserProps>({} as UserProps)
type UserContextProviderProps = {
children: React.ReactNode
}
const UserContextProvider = ({children}: UserContextProviderProps) => {
const [user, setUser] = useState<{} | null>(null)
useEffect(() => {
const loggedInUser = localStorage.getItem("user");
if (loggedInUser) {
setUser(JSON.parse(loggedInUser));
}
}, [])
return (
<UserContext.Provider value={{user, setUser}}>
{children}
</UserContext.Provider>
)
}
export default UserContextProvider
LoginPage.tsx: This is the login page where i am using the context
const [email, setEmail] = useState<string>('')
const [password, setPassword] = useState<string>('')
const [redirect, setRedirect] = useState<boolean>(false)
const {setUser, user}: UserProps = useContext(UserContext)
const handleLogin = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault()
try {
const {data} = await axios.post('/auth/login', {email,password})
setUser(data)
localStorage.setItem('user', JSON.stringify(data))
setRedirect(true)
console.log(user)
} catch (error) {
return error
}
if(redirect) {
return <Navigate to={'/dashboard'} />
}
Dashboard .tsx:
import React, {useContext, useState} from 'react'
import { Navigate } from "react-router-dom";
import { UserContext } from '../UserContext'
import { UserProps } from '../types'
const Dashboard = () => {
const {setUser, user}: UserProps = useContext(UserContext)
const [redirect,setRedirect] = useState<boolean>(false);
const handleLogout = () => {
setUser(null)
localStorage.removeItem("user")
setRedirect(true)
}
if(redirect){
return <Navigate to={'/'} />
}
if(!user){
return <Navigate to={'/login'}/>
}
return (
<div className='flex flex-col'>
<p>DashBoard</p>
<p>{user?.name}</p>
<button className='border border-black w-[100px]' onClick={handleLogout} >Log Out</button>
</div>
)
}
export default Dashboard