我有一个更新表格来更新用户的信息。
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]
在幕后如何工作?进行此状态更改的正确方法是什么?
答案 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
发送的新用户对象。您可以通过两种方式解决此问题。您可以展平状态对象,并在状态中设置firstName
,lastName
和email
,如下所示:
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
});
};