我在组件状态下具有以下数据结构。所有状态属性都是受控组件。
System.setProperty("file.encoding","UTF-8");
System.setProperty("sun.jnu.encoding","UTF-8");
例如,将第一级属性“公司名称”定义为
new String(byteArray, "UTF-8")
和第二级属性“ firstName”定义为
constructor(props) {
super(props);
this.state = {
companyName: '',
country: '',
contact: {
firstName: '',
lastName: '',
email: '',
phone: ''
}
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
我当前的handleChange(e)方法会更新状态,但会向该状态添加2级属性。更新状态的正确方法是什么?
<Input label="Company Name" name="companyName" id="companyName" type="text" value={this.state.companyName} onChange={this.handleChange} required/>
答案 0 :(得分:2)
constructor(props) {
super(props);
this.state = {
companyName: '',
country: '',
contact: {
firstName: '',
lastName: '',
email: '',
phone: ''
}
};
// this.handleChange = this.handleChange.bind(this); => remove this, you don't need this, bind your functions where you define them using `=>` like I did in the example below
}
对于您的输入字段
<Input label="Company Name" name="companyName" id="companyName" type="text" value={this.state.companyName} onChange={this.handleChange('rootLevel')} required />
第二层财产
<Input label="First Name" name="firstName" id="firstName" type="text" value={this.state.contact.firstName} onChange={this.handleChange('contact')} required/>
onChange
方法应该像这样
handleChange = type => event => {
if (type === "rootLevel") {
this.setState({ [event.target.name]: event.target.value });
return;
}
const { name, value } = event.target;
this.setState({
[type]: {
...this.state[type],
[name]: value
}
});
};
作为参考,我已在Codesandbox中复制了此代码,您可以查看[here]。
答案 1 :(得分:1)
此问题是由于您两次添加[name]: value
而引起的。因此,如果更新第一级属性,则还添加第二级属性,反之亦然。
我建议您使状态完全平坦。这样,您可以继续使用相同的handleChange
方法。
state = {
companyName: '',
country: '',
firstName: '',
lastName: '',
email: '',
phone: ''
};
否则,您必须在handleChange
方法中告诉您要更新属性的级别。像这样:
handleChange(event, level) {
if (level === 1) { // or whatever way you think is best to get the right level
this.setState({
...this.state, [event.target.name]: event.target.value
});
} else {
this.setState({
...this.state,
content: {
...this.state.contact,
[event.target.name]: event.target.value
}
});
}
}
您的输入应如下所示:
<Input label="First Name" name="firstName" id="firstName" type="text" value={this.state.contact.firstName} onChange={(e) => this.handleChange(e, 2)} required/>
答案 2 :(得分:0)
您将[name]
用于第一级和第二级哈希。
因此,如果您编辑firstName
,它也会将firstName
添加到第一级。
试试这个。
handleChange(e) {
const { name, value } = e.target;
if(['companyName', 'country'].includes(name)){
this.setState( prevState => {
...prevState,
[name]: value
});
}else{
this.setState( prevState => {
...prevState,
contact: {
...prevState.contact,
[name]: value,
}
});
}
}
答案 3 :(得分:0)
由于有些人已经给出了一些解决方案。 让我们考虑一下可以使用几行代码的解决方案。
handleChange(e) {
let contact = this.state.contact;
if (contact.hasOwnProperty(e.target.name)) {
contact[e.target.name] = e.target.value;
}
this.setState({
[e.target.name]: e.target.value
});
}
此解决方案有效。我认为您不应该使这种事情变得过于复杂,而应该保持状态不变,并且在发送数据时应重新格式化。