我有一个简单的反应组件,我相信有一个受控输入的形式:
import React from 'react';
export default class MyForm extends React.Component {
constructor(props) {
super(props);
this.state = {}
}
render() {
return (
<form className="add-support-staff-form">
<input name="name" type="text" value={this.state.name} onChange={this.onFieldChange('name').bind(this)}/>
</form>
)
}
onFieldChange(fieldName) {
return function (event) {
this.setState({[fieldName]: event.target.value});
}
}
}
export default MyForm;
当我运行我的应用程序时,我收到以下警告:
警告:MyForm正在更改要控制的类型文本的不受控制的输入 . 输入元素不应从不受控制切换到受控制(或反之亦然) . 决定在组件的使用寿命期间使用受控或不受控制的输入元件
我相信我的输入是有控制的,因为它有一个值 . 我想知道我做错了什么?
我正在使用React 15.1.0
8 回答
在构造函数中将字段值设置为“”(空字符串)的一个潜在缺点是,如果字段是可选字段并且未编辑 . 除非在发布表单之前进行一些按摩,否则该字段将作为空字符串而不是NULL保留到数据存储中 .
这个替代方案将避免空字符串:
在输入中使用 onChange={this.onFieldChange('name').bind(this)} 时,必须将状态空字符串声明为属性字段的值 .
incorrect way:
correct way:
对于要控制的输入,其值必须与状态变量的值相对应 .
在您的示例中最初未满足该条件,因为最初未设置
this.state.name
. 因此,输入最初是不受控制的 . 首次触发onChange
处理程序后,this.state.name
将被设置 . 此时,满足上述条件并且认为输入受到控制 . 从不受控制到受控制的这种转变产生了上面看到的错误 .通过在构造函数中初始化
this.state.name
:例如
输入将从一开始就被控制,解决问题 . 有关更多示例,请参阅React Controlled Components .
与此错误无关,您应该只有一个默认导出 . 你上面的代码有两个 .
首次渲染组件时,未设置
this.state.name
,因此它的计算结果为undefined
,最后将value={undefined}
传递给input
.当ReactDOM检查字段是否被控制时,it checks to see if value != null(注意它是
!=
,而不是!==
),并且自JavaScript中的undefined == null
以来,它决定它是不受控制的 .因此,当调用
onFieldChange()
时,this.state.name
设置为字符串值,您的输入将从不受控制变为受控制 .如果在构造函数中执行
this.state = {name: ''}
,因为'' != null
,您的输入将始终具有值,并且该消息将消失 .另一种方法是在输入中设置默认值,如下所示:
我知道其他人已经回答了这个问题 . 但是,这里一个非常重要的因素可能会帮助其他人遇到类似的问题:
您必须在输入字段中添加
onChange
处理程序(例如textField,checkbox,radio等) . 并始终通过onChange
处理程序处理活动,如:当您使用 checkbox 时,您可能需要使用
!!
来处理其checked
状态:如果组件上的props已作为状态传递,请为输入标记设置默认值
在初始状态下将值设置为“name”属性 .