首页 > 解决方案 > react中的useState没有更新状态对象

问题描述

我创建了一个 stateObject 并在输入表单中有数据更改时更新状态。每当用户在输入表单中键入时,我想清除“错误”键中的值。

我尝试在第一步中使用 setState 将错误键设置为 null。但是它不起作用。但是当我在第二步中尝试相同时,错误键正在正确更新为空字符串。我不明白为什么第二步有效,而不是第一步。有人可以解释一下吗?

const [userdata,setuserData] = useState({name:"",email:"",password:"",error:""});

const {name, email, password , error } = userdata;

//runs when the onchange click event works

const handleChange = (name)=> (event) =>{
    setuserData({...userdata,error:""}) // First Step- This line is not working
    setuserData({...userdata,[name]:event.target.value,error:""}); //Second Step - This is working
}

return (
<div className="container">
    <h2 className="mt-5 mb-5">Signup</h2>
    
    {/* inline Conditional Rendering*/}
    <div className="alert alert-primary" 
         style={{display:error ? "" : "none"}}>
        {error}
    </div>

    <form>
        <div className="form-group">
                <label className="text-muted">Name</label>
                <input 
                onChange={handleChange("name")}
                value={name}
                type="text" className="form-control"/>
        </div>
        <div className="form-group">
                <label className="text-muted">Email</label>
                <input 
                onChange={handleChange("email")}
                value={email}
                type="email" className="form-control"/>
        </div>
        <div className="form-group">
                <label className="text-muted">Password</label>
                <input 
                onChange={handleChange("password")}
                value={password}
                type="password" className="form-control"/>
        </div>
        <button className="btn btn-raised btn-primary"
        onClick={handleSubmit}>
            Submit
        </button>
    </form>
</div>  )

标签: reactjsuse-state

解决方案


状态设置是异步和批处理的。当您调用时,以前的内容userdata不会立即更新setuserData。结果,只有最终调用setuserData会在下一次渲染时处于新状态。

您需要在一次调用中同时设置这两个属性(或者使用回调表单):

setuserData({
  ...userdata,
  error: '', // or null?
  [name]: :event.target.value,
});

使用类似上面的东西,once,或使用:

setuserData(userdata => ({ ...userdata, error: '' }));
setuserData(userdata => ({ ...userdata, [name]: event.target.value }));

(但第二个版本不必要地重复;如果可能,第一个选项更可取)


推荐阅读