3

I am making an authentication page following a tutorial but they create an array for useState, How do set or use this inside my formik form onChange like this they did.

const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [errorMsg, setErrorMsg] = useState("");
const [loginUser, { data, isError, error }] = useLoginUserMutation()


useEffect(() => {
    if (data && data.access_token) {
      localStorage.setItem(
        'login',
        JSON.stringify({
          userLogin: true,
          token: data.access_token
        })
      )
      setErrorMsg('')
      setEmail('')
      setPassword('');
      navigate('/about')
    }
    if (isError) {
      setErrorMsg(error.data.message)
    }
  }, [data, isError, error])

    const handleLogin = async (e) => {
    e.preventDefault()
    await loginUser({ email, password })
  }
  1. The form can't read the input value when I put the onChange statement inside this formik, I get email and password is required. It is supposed to read the value and onSubmit navigate to another page used inside the useEffect.

           <Formik
         initialValues={{
           email: '',
           password: '',
         }}
         validationSchema={validate}
         onSubmit={handleLogin}
       >
         {({ isSubmitting }) => (
           <Form className='py-4'>
             <div>
               <TextField
                 label='Email Address'
                 name='email'
                 type='email'
                 value={email}
                 onChange={(e) => setEmail(e.target.value)}
                 placeholder='mail@company.com'
               />
             </div>
    
             <div className='relative'>
               <TextField
                 label='Password'
                 name='password'
                 type={passwordShown ? 'text' : 'password'}
                 value={password}
                 onChange={(e) => setPassword(e.target.value)}
                 placeholder='******'
    
               />
               <i
                 className='fa-solid fa-eye absolute top-[50px] right-4 cursor-pointer'
                 onClick={togglePasswordVisiblity}
               ></i>
             </div>
    
             <div className='remember flex justify-between justify-items-center my-4'>
               <div className='check gap-2 flow-root'>
                 <input type='checkbox' name='rememberMe' id='remeberMe' />{' '}
                 Remember me
               </div>
               <Link
                 to='/ForgetPassword'
                 className='underline hover:underline hover:text-black'
               >
                 {' '}
                 Forget your password{' '}
               </Link>
             </div>
    
             <button
               type='submit'
               disabled={isSubmitting}
               className='border-0 py-2
               rounded hover:bg-[#0559FD]
               w-full bg-[#AAAAAA] text-white'
             >
               {' '}
               Log in{' '}
             </button>
           </Form>
         )}
       </Formik>
    

1 Answers1

0

I think that it has to do with this fragment of code executed in useEffect:

setErrorMsg('')
setEmail('')
setPassword('');

Let me explain what is happening here step by step:

  1. After each value change i.e. in email input, you are calling setEmail with the new value.
  2. After the state is changed, component gets rerendered,
  3. When the component gets rerendered, since data && data.access_token statement resolves to true, setEmail('') gets executed

How can you make sure I am right?

Put simple console.log('calling!') inside if statement of useEffect, then change the value of email input - verify if console.log() gets called every time after you change the value.

How can you fix this?

One of the solutions can be moving the code responsible of resetting inputs values to onSubmit function.

vnav
  • 1