After changing UseState Hook React component not re-rendering
1 min read
I am new at React and i am trying to develop a login page. I did almost all but I could not re-render after successful login. I need to refresh the page to see the protected content. As far as I know, using custom Hook and changing its value should trigger a component re-render but although I change the value of it (token), page is not re-rendered. What is the point i missed?
//App.js
function App() {
const { token, setToken } = useToken();
if(!token) {
return <Login setToken={setToken} />
}
return (
<div className="wrapper">
<h1>Application</h1>
<BrowserRouter>
<Routes>
<Route path="/" element={<Dashboard />} />
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
//UseToken.js
export default function useToken() {
const getToken = () => {
const tokenString = localStorage.getItem('token');
const userToken = JSON.parse(tokenString);
return userToken;
};
const [token, setToken] = useState(getToken());
const saveToken = userToken => {
localStorage.setItem('token', JSON.stringify(userToken));
setToken(userToken.token);
};
return {
setToken: saveToken,
token
}
}
//Login.js
async function loginUser(credentials) {
return fetch('http://localhost:8080/user', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(credentials)
}).then(data => data.json())
.then(response => response.token)
}
export default function Login({ setToken }) {
const [username, setUserName] = useState();
const [password, setPassword] = useState();
const handleSubmit = async e => {
e.preventDefault();
const token = await loginUser({
username,
password
});
setToken(token);
}
return(
<div className="login-wrapper">
<h1>Please Log In</h1>
<form onSubmit={handleSubmit}>
<label>
<p>Username</p>
<input type="text" onChange={e => setUserName(e.target.value)}/>
</label>
<label>
<p>Password</p>
<input type="password" onChange={e => setPassword(e.target.value)}/>
</label>
<div>
<button type="submit">Submit</button>
</div>
</form>
</div>
)
}
Login.propTypes = {
setToken: PropTypes.func.isRequired
}
//Dashboard.js
export default function Dashboard() {
const logout = () => {
localStorage.clear();
}
return(
<div>
<h2>Dashboard</h2>
<button type="button" onClick={logout}>Logout</button>
</div>
);
}
資料來源:Stackoverflow