简体   繁体   中英

Can't update state using useState

I'm trying to update the state of my component with useState in a register functional component。 when user input an invalid email address and click the submit button, the following piece of code will return an error message

let response= await axios.post("/api/user/register",new_user,config);

I want to set error message into formData with this piece of code .

        let response= await axios.post("/api/user/register",new_user,config);
        if(response.data.errnum!==0){
            setFormData({...formData,errors:response.data.message})
            console.log(formData);
        }

but the value of errors is empty,like this结果截图

What should I do to set error message into formData?

Here is my code:

 import React ,{useState}from 'react' import axios from "axios" function Register() { const [formData,setFormData]=useState({ name:"", email:"", password:"", password2:"", errors:{} }); const {name,email,password,password2}=formData; const setValue= e =>setFormData({...formData,[e.target.name]:e.target.value}) const submitData=async (e) =>{ e.preventDefault(); if(password!==password2){ console.log("passwords do not match "); }else{ let new_user={name,email,password,} try{ let config={ header:{ 'Content-Type':'applicaiton/json' } } let response= await axios.post("/api/user/register",new_user,config); if(response.data.errnum!==0){ setFormData({...formData,errors:response.data.message}) console.log(formData); } }catch(error){ console.error(error); } } } return ( <div> <section className="container"> <h1 className="large text-primary">Sign Up</h1> <p className="lead"><i className="fas fa-user"></i> Create Your Account</p> <form className="form" onSubmit={e=>submitData(e)}> <div className="form-group"> <input type="text" placeholder="Name" name="name" value={name} onChange={e=>setValue(e)} required /> </div> <div className="form-group"> <input type="email" placeholder="Email Address" onChange={e=>setValue(e)} value={email} name="email" /> <small className="form-text">This site uses Gravatar so if you want a profile image, use aGravatar email</small> </div> <div className="form-group"> <input type="password" placeholder="Password" onChange={e=>setValue(e)} value={password} name="password" minLength="6" /> </div> <div className="form-group"> <input type="password" placeholder="Confirm Password" onChange={e=>setValue(e)} value={password2} name="password2" minLength="6" /> </div> <input type="submit" className="btn btn-primary" value="Register" /> </form> <p className="my-1"> Already have an account? <a href="login.html">Sign In</a> </p> </section> </div> ) } export default Register

I think what you are doing wrong is that you are saving and object inside another object

const [formData,setFormData]=useState({
    name:"",
    email:"",
    password:"",
    password2:"",
    errors:{}
});

formData is an object while errors is also an object.To go for a better approach make a seperate state for errors and append all the errors coming through those messages in an error object. If you write a message in errors object where it is defined it will give you error

errors:{"hi","bye"}

There is no issue in your code. What you are trying to do is console the state as soon as you are setting it up.

setState is asynchronous which means you can't call it on one line and assume the state has changed on the next.

If you check React docs

setState() does not immediately mutate this.state but creates a pending state transition. Accessing this.state after calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls to setState and calls may be batched for performance gains.

I'd suggest you use useEffect and then check for change in data of your state.

useEffect(() => {
console.log(formData)
}, [formData])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM