我有这样的表格:
construecter() {
this.state = { dispThumbnails: true };
}
handleChange(event) {
event.target.value = event.target.type === 'checkbox' ? event.target.checked : event.target.value;
this.setState({[event.target.name]: event.target.value});
}
render(){
return (
return (
<form onSubmit={() => this.handleSubmit(event, 1)}>
<select id='selection' name='selection' value={this.state.selection} onChange={this.handleChange}>
<option value='Option 1'>Option 1</option>
</select>
<input id='subject' name='subject' type='text' value={this.state.subject} onChange={this.handleChange}/>
<input id='dispThumbnails' name='dispThumbnails' type='checkbox' checked={this.state.dispThumbnails} onChange={this.handleChange}/>
<input type='submit' value="Search"/>
</form>
)
}
然而,输入框和选择框工作正常,但我从默认选中的复选框中得到了意外的行为:
- 第一次点击什么都不做,但在控制台中返回:"警告:收到布尔属性
checked
的字符串false
。浏览器会将其解释为一个真实的值。你是说checked={false}吗"> - 第二次单击取消复选框
- 第三次单击复选框
- 第四次单击不起任何作用,也不打印任何警告
- 第五次点击取消复选框
- 第六次点击复选框
- 重复
为什么?我很难理解这是怎么回事。
经过额外的研究和测试,我发现我可以将表单处理程序更改为:
handleChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
确实按预期运行,每次单击都会取消选中并选中该框。
但是,为什么呢?除了使用一些中间变量之外,我看不出它在功能上与我的原始代码有什么不同。
没有理由不使用更新后的代码,但为了学习,如果有人能解释为什么原始示例失败,我将不胜感激。谢谢
根据construecter() {
的拼写错误,我猜您的状态没有初始化。这就是为什么在你第一次点击时什么都没有发生的原因。您将复选框从非受控输入(因为未设置状态,所以将value
设置为undefined
(改为受控输入。我不知道为什么它会说你在传递一个字符串,但我想知道这是否是一个从一个移动到另一个的工件。
然后这行:
event.target.value = event.target.type === 'checkbox' ? event.target.checked : event.target.value;
你不应该设置目标的值,我不确定它是否可写。您应该创建自己的变量并使用它。
所以在第二次点击时它就起作用了,因为它现在被控制了,在第三次点击时又一次。我不确定之后会发生什么,但这肯定是向event.target.value
写入的一些副作用。
你可以简单地做:
handleChange(event) {
const value = event.target.type === 'checkbox' ? event.target.checked : event.target.value;
this.setState({
[event.target.name]: value
});
}
或
handleChange(event) {
this.setState({
[event.target.name]: event.target.type === 'checkbox' ? event.target.checked : event.target.value
});
}
或者你的第二个例子很好。只是不要为受控组件写入事件的目标值。