我在React组件中有这个构造函数:
constructor() {
super();
this.state = {
info: {
title: '',
description: '',
height: ''
}
}
...
还有一个状态由输入控制的表单:
<form onSubmit={this.handleFormSubmit}>
<label>Title:</label>
<input type="text" name="title" value={this.state.info.title} onChange={(e) => this.handleChange(e)} />
<label>Description:</label>
<input type="text" name="description" value={this.state.info.description} onChange={(e) => this.handleChange(e)} />
...
当我在表单上键入任何内容时,我想我的处理程序有问题,因为我得到警告“ 警告:组件正在将文本类型的受控输入更改为不受控制。输入元素不应切换从受控变为非受控(反之亦然)。决定在组件的使用寿命中使用受控或非受控输入元素。“
检查控制台,似乎状态正在更新正在键入的每个属性值,并删除其他属性,而应该保留所有这些属性,而仅更新更改的属性。
这是我的处理程序:
handleChange(event) {
let { name, value } = event.target;
this.setState({
info: {
[name]: value
}
});
}
答案 0 :(得分:3)
您正在使用的一个仅更新一个道具,而其他被剥离的导致React的警告显示。您可以使用传播来保持其他人
handleChange(event) {
let { name, value } = event.target;
this.setState({
info: {
...this.state.info,
[name]: value
}
});
}
答案 1 :(得分:1)
通常有2种情况会在我的经历中引起这种警告。
答案 2 :(得分:1)
尝试一下:
handleChange(event) {
let { name, value } = event.target;
this.setState(({info}) =>({
info: {
[name]: value
}
}));
}
中断函数调用:
this.setState(updaterFunction)
。 updaterFunction
由setState
调用,并以先前的状态作为参数,并且该函数应返回一个带有要更新的状态键的对象(它与先前的状态浅合并)。 / li>
setState
只是 shallow 合并(无论您传递的是对象还是函数),如果您有一个像this.state.foo.bar
一样的对象,并且您进行更新状态为{foo: {bar: 'qux'} }
之类的对象,旧的foo
将不会与新的foo合并,而是会被替换。因此,您的更新程序功能需要手动进行更深层次的合并。({info})=>({…})
。我们将info
从先前的状态中拉出,然后返回一个对象,并使用info
手动进行更深的合并。将函数传递给setState
(而不仅仅是对象)的好处是,如果您使用传递给函数的状态而不是this.state
,则当多个{ {1}}个呼叫被汇总在一起。...