Reputation: 1131
Navbar.js
import React from 'react'
import { useHistory } from 'react-router'
import { useEffect } from 'react'
import { useState } from 'react'
const Navbar = () => {
let history = useHistory()
let [token, setToken] = useState('')
const logout = () => {
setToken(window.localStorage.removeItem('token'))
history.push('/login')
}
useEffect(() => {
setToken(window.localStorage.getItem('token'))
})
return (
<nav>
<div className='nav-content'>
<h1>LunCare <i class="fas fa-plus"></i></h1>
{
token !== null ?
<ul>
<li>
<a href='' onClick={logout}>Logout</a>
</li>
</ul>
:
<ul>
<li>
<a href='/register'>Register</a>
<a href='/login'>Login</a>
</li>
</ul>
}
</div>
</nav>
)
}
export default Navbar
Login.js (I dont think this is needed but ill include it)
import React from 'react'
import { useHistory } from 'react-router'
const Login = () => {
let user = {
username: '',
password: ''
}
let error = false
let history = useHistory()
const login = (e) => {
e.preventDefault()
fetch('http://127.0.0.1:8000/auth/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(user)
}).then(res => {
if(res.status === 200 || res.status === 201) {
return res.json()
} else {
error = true
}
})
.then(data => {
window.localStorage.setItem('token', data.token);
history.push('/')
})
.catch(err => {
})
}
const updateForm = (e) => {
e.preventDefault()
user[e.target.name] = e.target.value
}
return (
<div className='form-container'>
<form onSubmit={login}>
<div className='form-content'>
<h1>Log In</h1>
<label>Name</label>
<input type='text' name='username' onChange={updateForm}></input>
<label>Password</label>
<input type='password' name='password' onChange={updateForm}></input>
<button type='submit'>Log In</button>
</div>
</form>
</div>
)
}
export default Login
Everything works as intended, but when I successfully login the navbar doesnt change accordingly... I need to refresh it so that it detects the token, how can I make it so that the navbar changes when the user gets redirected after logging in, any help is appreciated!
Upvotes: 0
Views: 150
Reputation: 3665
token
to a common parent component say Parent
that renders, Nav
and Login
.Parent
should you declare the state, token
.token
function to Login
, use that on your login handler function// Login.js
...
const Login = ({ setToken }) => { // destructure `setToken`
const login = (e) => {
...
.then(data => {
window.localStorage.setItem('token', data.token);
setToken(data.token); // set the token here
history.push('/')
})
.catch(err => {
})
...
}
}
token
and setToken
to your Nav
componentconst Navbar = ({ token, setToken }) => { // destructure token and setToken here
...
// let [token, setToken] = useState('') // don't need this
const logout = () => {
window.localStorage.removeItem('token')
setToken(null) // need to clear state after logging out
history.push('/login')
}
/* Don't need this either
useEffect(() => {
setToken(window.localStorage.getItem('token'))
})
*/
...
}
Upvotes: 1