I am attempting to load my register component when a button is clicked in my login component using useNavigate hook but when I add onClick={navigate('/register', {replace: true})}
in the button, it makes it so that when I click the login link in my navigation bar, it is loading /register instead of my login form. Am I supposed to be using a Link instead or what am I doing wrong? Any help is appreciated, thank you so much!
import React, {useState, useEffect} from 'react';
import {useDispatch, useSelector} from 'react-redux';
import {Link, useNavigate} from 'react-router-dom';
import {Formik, Field, Form, ErrorMessage} from 'formik';
import * as Yup from 'yup';
import {login} from '../../slices/auth';
import {clearMessage} from '../../slices/messages';
const Login = (props) => {
const navigate = useNavigate();
const [loading, setLoading] = useState(false);
const {isLoggedIn} = useSelector((state) => state.auth);
const {message} = useSelector((state) => state.message);
const dispatch = useDispatch();
useEffect(() => {
dispatch(clearMessage());
}, [dispatch]);
const initialValues = {
username: '',
password: '',
};
const validationSchema = Yup.object().shape({
username: Yup.string().required('Please enter your Username'),
password: Yup.string().required('Please enter your Password'),
});
const handleLogin = (formValue) => {
const {username, password} = formValue;
setLoading(true);
dispatch(login({username, password}))
.unwrap()
.then(() => {
navigate('/profile', {replace: true});
})
.catch(() => {
setLoading(false);
});
};
if (isLoggedIn) {
return <Link to='/profile' />;
}
return (
<div className='login'>
<div className='form-container'>
<h1 id='welcome-plate'>Welcome, please Login</h1>
<div className='button-box'>
<div id='btn'>
<button type='button' className='toggle-btn' id='login-option'>
Login
</button>
<button
type='button'
className='toggle-btn'
id='register-option'
onClick={navigate('/register', {replace: true})}
>
Register
</button>
</div>
</div>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={handleLogin}
>
<Form>
<div className='login-group'>
<Field
name='username'
type='text'
className='form-control'
placeholder='User ID'
/>
<ErrorMessage
name='username'
component='div'
id='username-error'
/>
</div>
<div className='login-group'>
<Field
name='password'
type='password'
className='form-control'
placeholder='Enter Password'
/>
<ErrorMessage
name='password'
component='div'
id='password-error'
/>
</div>
<div className='login-group'>
<button type='submit' className='login-btn' disabled={loading}>
{loading && (
<span className='spinner-border spinner-border-sm'></span>
)}
<span>Login</span>
</button>
</div>
</Form>
</Formik>
</div>
{message && (
<div className='form-group' id='alert'>
<div className='alert alert-danger' role='alert'>
{message}
</div>
</div>
)}
</div>
);
};
export default Login;
CodePudding user response:
onClick={navigate('/register', { replace: true })}
This is immediately invoking the navigate
function. You want to pass a callback function to the onClick
handler that then calls navigate
to issue the imperative redirect.
onClick={() => navigate('/register', { replace: true })}