I am trying to redirect user after successful login. I did it this way but it does not work. How can I fix this issue or how can I do it correctly?
main.jsx
Login.jsx
imports ...
function Login() {
const [login, setLogin] = useState('');
const [password, setPassword] = useState('');
const [loginClass, setLoginClass] = useState('');
const [passwordClass, setPasswordClass] = useState('');
const [isLoggedIn, setIsLoggedIn] = useState(false);
const submit = async (evt) => {
evt.preventDefault();
console.log(login, password);
if (login.length === 0 || password.length === 0) {
console.log('stop')
if (!login) {
setLoginClass('is-invalid');
}
if (!password) {
setPasswordClass('is-invalid');
}
} else {
console.log('req')
await axios
.post('http://localhost:5000/test/auth/login', {
login: login,
password: password
})
.then((response) => {
console.log(response);
const { data } = response;
if (data.status == 200) {
console.log('entered successfully');
setIsLoggedIn(true);
} else {
console.log('could not enter');
}
})
.catch((error) => {
console.log(error);
});
setPassword('');
setLogin('');
setLoginClass('');
setPasswordClass('');
}
if (isLoggedIn) {
return <Navigate to="/main" replace={true}/>
}
return
};
return (
<div className="container col-xl-10 col-xxl-8 px-4 py-5">
...
<input
type="text"
className={`form-control ${loginClass}`}
id="login"
placeholder="Login"
value={login}
onChange={(evt) => { setLogin(evt.target.value) }}
/>
...
<input
type="password"
className={`form-control ${passwordClass}`}
id="password"
placeholder="Password"
value={password}
onChange={(evt) => { setPassword(evt.target.value) }}
/>
<button className="w-100 btn btn-lg btn-primary" onClick={submit}>Enter</button>
</form>
</div>
</div>
</div>
);
}
export default Login;
2
Answers
One of the ways to achieve navigation in your React application is to use the
useNavigate
hook fromreact-router-dom
Modify this condition in your submit function
Issues
Attempting to return JSX from an asynchronous callback function.
The code is attempting to issue a redirect from within the submit handler. You can’t return JSX from a callback and expect it to be rendered to the DOM and have any effect.
Navigate
would need to be returned from theLogin
as part of the regular JSX it renders.Attempting to access a stale closure over state.
submit
enqueues some state updates and the code incorrectly attempts to access theisLoggedIn
state to effect a redirect action.It is generally considered a Javascript anti-pattern to mix
async/await
with Promise chains. Pick one pattern or the other.Solutions
Enqueue the
isLoggedIn
state update as you are and return theNavigate
component with the regular JSX to issue a declarative redirect.Use the
useNavigate
hook and issue an imperative redirect from the submit handler.