Why useState object value is not updating using onBlur event in react js?

Viewed 44

I have textfield component

<MyTextField
    type={inpValues.emailID.type}
    label={inpValues.emailID.label}
    name={inpValues.emailID.name}
    placeholder={inpValues.emailID.placeHolder}
    required={inpValues.emailID.required}
    error={inpValues.emailID.error}
    helperText={inpValues.emailID.helperText}
    
    handleOnBlur={(event) => {
        //console.log("Call HandleOnBlur");
        setInpValues({...inpValues, email:{
            ...inpValues.emailID,
            value:event.target.value
        }})
        HandleEmailOnBlur(inpValues.emailID.value)
        }
    }
    value={inpValues.emailID.value}
></MyTextField>

HandleEmailOnBlur function

const HandleEmailOnBlur = (emailID) =>{
    if(emailID.trim().length > 0){
        let email = emailID;
        emailValidation(email)
    }

    if(inpValues.emailID.error === false){
        //.... if it is false i will call server using AXIOS
    }
}
function emailValidation(email) {
    console.log('Email Validation Called, Email = '+ email)
    if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {
        return ('')
    }
    else {
      
        //below codes are executed
        setInpValues({
            ...inpValues,
            emailID: {
                ...inpValues.emailID,
                error: true,
                helperText: 'Please enter valid Email ID' // I can see this text message on browser
            }
        })
    }

    //but when i check the object value in console. it is not updated, why?
    console.table(inpValues)
}

I can call emailValidation(email) function. it set the values of error:true, helperText:'Please enter valid Email ID',

helperText is updated on the browser, but it's not updated on the useState object value

console

I tried with prevState like below, still same result

setInpValues(prevInpValues => ({
   ...prevInpValues,
   emailID: {
       ...prevInpValues.emailID,
       error: true,
       helperText: 'Please enter valid Email ID'
       }
    })
)
1 Answers

as it was said in the comments updating state maybe async but if you want to ensure that your state updating is synchronous you can put setState in a flushSync function. so you can rewrite emailValidation function as following.

function emailValidation(email) {
console.log('Email Validation Called, Email = '+ email)
if (/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {
    return ('')
}
else {
  
    //below codes are executed
    flushSync(() => {setInpValues({
        ...inpValues,
        emailID: {
            ...inpValues.emailID,
            error: true,
            helperText: 'Please enter valid Email ID' // I can see this text message on browser
        }
    })})
}

//but when i check the object value in console. it is not updated, why?
console.table(inpValues) }

this way console.table(inpValues) will receive updated values of state and DOM is ensured to be updated with new values

Related