使用[event.target.name],React组件的状态如何变化?

时间:2019-04-15 10:31:11

标签: javascript reactjs

我有一个更新表格来更新用户的信息。

 const { basic: userBasic } = this.state.user; 

 <Modal open={openEditBasicModal} size="small">
      <Modal.Header>Your basic details</Modal.Header>
      <Modal.Content scrolling>
        <Form>
          <Form.Group inline widths="equal">
            <Form.Input
              fluid
              type="text"
              name="firstName"
              defaultValue={userBasic.firstName}
              onChange={this.handleBasicFromInputValue}
              label="First Name"
            />
            <Form.Input
              fluid
              type="text"
              name="lastName"
              defaultValue={userBasic.lastName}
              onChange={this.handleBasicFromInputValue}
              label="Last Name"
            />
          </Form.Group>             
        </Form>
      </Modal.Content>
      <Modal.Actions open={true}>
        <Button
          primary
          onClick={this.updateUserBasicInfo}>
          Update
        </Button>
      </Modal.Actions>
    </Modal>

组件的状态为:

this.state = {
      user: {
        basic: {
          firstName: null,
          lastName: null,
          email: null
        },
        //others
      }
}

表单中的默认值来自state,逻辑是通过在表单字段上使用state处理程序来更新onChange。因此,我为此使用了一个简单的处理程序:

handleBasicFromInputValue = event => {
    this.setState({
      user: {
        basic: {
          [event.target.name]: event.target.value
        }
      }
    });
  };

上述处理程序 DID 更新状态,它还删除了组件中声明的state模式。如果用户状态为

user: {
    basic: {
      firstName: "theCoder",
      lastName: "lastCoder",
      email: "something@gmail"
    }
}

现在我更新表单中的firstName字段,状态更改为

user: {
    basic: {
      firstName: "theCoderUpdated",
    }
}

如果我现在在表单提交中打印用户状态:

  updateUserBasicInfo = () => {
    console.log(this.state.user.basic);
  }

仅打印包含firstName: "theCoderUpdated"的对象

所有其他状态变量都消失了。其他状态变量不应该保持不变吗?
我认为是引起问题的[event.target.name],但我不确定为什么。

[event.target.name]在幕后如何工作?进行此状态更改的正确方法是什么?

5 个答案:

答案 0 :(得分:2)

您正在替换基本对象。这样做是为了保留以前的道具

status & 0b10000000 == 128 # email verified
status & 0b01000000 == 64  # phone verified
status & 0b00100000 == 32  # KYC passed
status & 0b00010000 == 16  # MFA set up
status & 0b00001000 == 8   # may transact
status & 0b00000100 == 4   # active
status & 0b00000010 == 2   # suspended
status & 0b00000001 == 1   # closed

答案 1 :(得分:1)

反应仅进行浅层状态合并。您可以在这里阅读有关内容:

https://reactjs.org/docs/state-and-lifecycle.html#state-updates-are-merged

这意味着当您调用setState时,所有顶级属性都将被完全替换。对您来说,这意味着user已完全替换为您用setState发送的新用户对象。您可以通过两种方式解决此问题。您可以展平状态对象,并在状态中设置firstNamelastNameemail,如下所示:

this.state = {
  firstName: null,
  lastName: null,
  email: null
}

或者您必须像这样更新状态:

handleBasicFromInputValue = event => {
    this.setState({
      user: {
        basic: {
          ...this.state.user.basic,
          [event.target.name]: event.target.value
        }
      }
    });
  };

答案 2 :(得分:0)

我认为您的问题是在创建新状态时不维护旧值。

尝试一下:

    handleBasicFromInputValue = event => {
      const { user } = this.state;        
      this.setState({
          user: {
            ...user,
            basic: {
              ...user.basic,
              [event.target.name]: event.target.value
            }
          }
        });
      };

当您执行“ setState”时,您正在创建一个新状态,这样您就可以更改所需的内容,但还必须保持已有的内容

您可以在React docs

中看到

使用spread operator,您可以复制已拥有的内容,并添加要更改的内容。

PS:您要更改的内容总是落后于已拥有的内容,因为否则,由于您正在复制以前的内容,因此可以替换它。

希望我能对您有所帮助:)

答案 3 :(得分:0)

您正在替换基本对象。你可以做到的。

this.state.user.basic [event.target.name] = event.target.value; this.setState({user:this.state.user});

答案 4 :(得分:0)

当您分配firstName时,您将状态替换为新状态,因为您将超越浅表副本。您必须这样做:

handleBasicFromInputValue = (event) => {
   var temp = this.state.user;
   temp.basic[event.target.name] = event.target.value;
   this.setState({
      user: temp
   });
 };