为了账号安全,请及时绑定邮箱和手机立即绑定

如果我使用传播运算符,为什么状态会更新为最新消息?

如果我使用传播运算符,为什么状态会更新为最新消息?

白猪掌柜的 2023-05-25 18:11:08
我有一个 React 应用程序,其中有一个包含一些字段和验证的表单。但是,验证没有像我期望的那样工作。代码如下:state = {  user: null,  errors: {}}onSubmitHandler = e => {  e.preventDefault();  //Check if first Name is returned empty  if (this.state.user.name.trim().length === 0) {    this.setState({      errors: {        ...this.state.errors,        name: "This field is required"      }    });  }  //Check if last name is returned empty  if (this.state.user.surname.trim().length === 0) {    this.setState({      errors: {        ...this.state.errors,        surname: "This field is required"      }    });    return;  }}现在,当我不提供两个输入字段并将它们留空时,我希望我的状态显示两个错误消息,即errors: {name: "This field is required", surname: "This field is required"}但我只收到最近的姓氏错误。所以我的结果显示像errors: {surname: "This field is required"}为什么它会覆盖第一条错误消息?任何帮助,将不胜感激。输入字段的代码未显示,因为它们只是带有 onChange 事件处理程序的输入标签。
查看完整描述

2 回答

?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

this.setState中的两个调用onSubmitHandler将一起进行批处理。

来自React Docs - setState():

将 setState() 视为请求而不是更新组件的即时命令。为了更好地感知性能,React 可能会延迟它,然后在一次传递中更新多个组件。React 不保证状态更改会立即应用。

setState() 并不总是立即更新组件。它可能会分批更新或将更新推迟到以后。这使得在调用 setState() 之后立即读取 this.state 成为一个潜在的陷阱

所以当你这样做时...this.state.errorsthis.state.errors在两个if块中,指的是一个空对象。结果,您只能在状态中看到对象surname中的键。errors

您可以通过复制this.state.errors对象来解决此问题,在复制的对象中添加键,然后将该复制的对象传递给this.setState.

onSubmitHandler = e => {

    e.preventDefault();

    

    // clone the "errors" object

    const errors = { ...this.state.errors };

    

    //Check if first Name is returned empty

    if(this.state.user.name.trim().length === 0) {

         errors.name = "This field is required";

    }

            

    //Check if last name is returned empty

    if(this.state.user.surname.trim().length === 0) {

        errors.surname = "This field is required";

    }


    this.setState({ errors });

}


查看完整回答
反对 回复 2023-05-25
?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

这是因为第二次传播仍然使用 this.state.errors 的旧值,因为它还没有改变。在执行 onSubmitHandler 之后,两个 setStates 可能(在您的情况下:肯定是)稍后进行状态更新。

将 setState 参数更改为自动使用最新状态的函数:

onSubmitHandler = e => {

  e.preventDefault();

  //Check if first Name is returned empty

  if (this.state.user.name.trim().length === 0) {

    this.setState(state => ({

      errors: {

        ...state.errors,

        name: "This field is required"

      }

    }));

  }

  //Check if last name is returned empty

  if (this.state.user.surname.trim().length === 0) {

    this.setState(state => ({

      errors: {

        ...state.errors,

        surname: "This field is required"

      }

    }));

    return;

  }

}


查看完整回答
反对 回复 2023-05-25
  • 2 回答
  • 0 关注
  • 151 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号