I am creating a social media app and when I log in with the user, I'm saving the token in the local storage and also putting in context the user's information to use it in several components after, and its working, but when I refresh the pages, the data disappear and the context is undefined. What am I doing wrong?
My App.js
function App() {
const [userData, setUserData] = useState({
name: "",
lastname: "",
username: "",
email: "",
});
return (
<Router>
<userContext.Provider value={{ userData, setUserData }}>
<div className="app">
<Switch>
<Route exact path="/" component={Login} />
<Route path="/register" component={Register} />
<Route path="/home" component={Home} />
<Route path="/profile" component={Profile} />
</Switch>
</div>
</userContext.Provider>
</Router>
);
}
My Login.js
function Login() {
const history = useHistory()
const {userData, setUserData} = useContext(userContext)
const [loginUser, setLoginUser] = useState({
email: '',
password: ''
})
const [error, setError] = useState()
const {email, password} = loginUser
const handleOnChange = (e) => {
setLoginUser({ ...loginUser, [e.target.name]: e.target.value})
}
const handleOnSubmit = (e) => {
e.preventDefault()
axios.post("http://localhost:5000/login", loginUser)
.then((res) => {
setUserData({
name: res.data.user.name,
lastname: res.data.user.lastname,
username: res.data.user.username,
email: res.data.user.email,
})
localStorage.setItem("auth-token", res.data.token)
history.push("/home")
})
.catch(err => {
err.response.data.msg && setError(err.response.data.msg)
})
}
return (
<div className="login">
<div>
<form onSubmit={handleOnSubmit} className="login-form">
{error ? <h4 className='login-error'>{error}</h4> : ""}
<input type="email" placeholder="Email or username" value={email} name='email' onChange={e => handleOnChange(e)}/>
<input type="password" placeholder="Password" value={password} name='password' onChange={e => handleOnChange(e)}/>
<Button type="submit" variant="contained">Log in</Button>
<div></div>
<p>Don't have an account? <Link to="/register">Click here</Link></p>
</form>
<h1>Raise your word <TwitterIcon className="login-right-icon"/></h1>
</div>
</div>
)
}
My Home.js where if I refresh I lose the data from the context
function Home() {
const {userData, setUserData} = useContext(userContext)
const [posts, setPost] = useState([])
const [createPost, setCreatePost] = useState('')
const handleToken = () => {
localStorage.removeItem('auth-token')
}
const token = localStorage.getItem("auth-token");
const handleOnSubmit = (e) => {
e.preventDefault()
axios.post('http://localhost:5000/posts', {textOfThePost: createPost}, {
headers: { 'auth-token': token },
})
.then((res) => {setCreatePost("")})
}
useEffect(() => {
axios.get('http://localhost:5000/posts')
.then(res => {
setPost(res.data)
})
}, [createPost])
return (
<div className="home">
<div style={{display: 'flex', alignItems: 'center'}}>
<h1>this is the home: Welcome, {userData.username}</h1>
<Link style={{margin: 10}} to="/home">home</Link>
<Link style={{margin: 10}} to="/profile">profile</Link>
<Link style={{margin: 10}} onClick={handleToken} to="/">log out</Link>
</div>
<form onSubmit={handleOnSubmit}>
<input type="text" placeholder="What's happening?" value={createPost} onChange={e => setCreatePost(e.target.value)}/>
<button type="submit">tweet</button>
</form>
<div style={{display: 'flex', flexDirection: 'column'}}>
{posts.map(post => (
<div style={{border: '2px solid black', marginBottom: 10, marginRight: 'auto', marginLeft: 'auto', width: 300}} key={post._id}>
<div style={{display: 'flex', alignItems: 'center'}}>
<Avatar src={post.avatar}/>
<span style={{color: 'blue', marginLeft: 10}}>{post.name} <span style={{color: 'grey', fontSize: 11}}>@{post?.username}</span></span><br/>
</div>
<span>{post.textOfThePost}</span><br/>
<span>{moment(post.date).format('lll')}</span>
</div>
)).reverse()}
</div>
</div>
)
}