Search code examples
javascriptreactjsformsreact-hooksuse-state

is it good in react to put a variable as a state value and update it directly


now I'm working with react form validation logic

I saw some tutorials on the internet about validating a form in react

and they made a normal variable and put it as a value to a state and update it directly without calling the "set" function provided by react like that

let errorsObject = {email: "", password: ""};
const [errors, setErrors] = useState(errorsObject)

and they update the variable directly like that

const onSubmit = (e) => {
   e.preventDefault();
   if (emailValue === "") {
      errorsObject.email = "please fill in this field"
   }
}

now I think this is wrong to update the state value like that I know the the best way to update a state is like that

if (emailValue === "") {
      setError({email: "please fill in this field"})
}

but there is a problem here

if I updated the state like this it overrides the state last data

and If I tried to get the latest state data like this

setErrors((prevState) => {
   return {...prevState, email: "please fill in this field"}
})

there is another error

If I submitted the form again and eddited email input data, the last validation data will be stored from the last check!

I hope you understand this, and If there another way to validate a form please tell me

and Thank you all


Solution

  • You're right, doing

    errorsObject.email = "please fill in this field"
    

    is definitely a mistake in React - state should not be mutated.

    Updating the object's state by doing

    setErrors((prevState) => {
       return {...prevState, email: "please fill in this field"}
    })
    

    is the right approach.

    If I submitted the form again and eddited email input data, the last validation data will be stored from the last check!

    Reset all of the error properties at the point that the errors get checked - don't update the email property only when there's a problem. Since it sounds like you have an email and password, you might want something like:

    const onSubmit = (e) => {
        e.preventDefault();
        setError({
            email: emailValue === '' ? "please fill in this field" : '',
            password: passwordValue === '' ? "please fill in this field" : '',
        });
    };