首页 文章

反应 - 改变不受控制的输入

提问于
浏览
150

我有一个简单的反应组件,我相信有一个受控输入的形式:

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 回答

  • 1

    在构造函数中将字段值设置为“”(空字符串)的一个潜在缺点是,如果字段是可选字段并且未编辑 . 除非在发布表单之前进行一些按摩,否则该字段将作为空字符串而不是NULL保留到数据存储中 .

    这个替代方案将避免空字符串:

    constructor(props) {
        super(props);
        this.state = {
            name: null
        }
    }
    
    ... 
    
    <input name="name" type="text" value={this.state.name || ''}/>
    
  • 1

    在输入中使用 onChange={this.onFieldChange('name').bind(this)} 时,必须将状态空字符串声明为属性字段的值 .

    incorrect way:

    this.state ={
           fields: {},
           errors: {},
           disabled : false
        }
    

    correct way:

    this.state ={
           fields: {
             name:'',
             email: '',
             message: ''
           },
           errors: {},
           disabled : false
        }
    
  • 217

    我相信我的输入是有控制的,因为它有一个值 .

    对于要控制的输入,其值必须与状态变量的值相对应 .

    在您的示例中最初未满足该条件,因为最初未设置 this.state.name . 因此,输入最初是不受控制的 . 首次触发 onChange 处理程序后, this.state.name 将被设置 . 此时,满足上述条件并且认为输入受到控制 . 从不受控制到受控制的这种转变产生了上面看到的错误 .

    通过在构造函数中初始化 this.state.name

    例如

    this.state = { name: '' };
    

    输入将从一开始就被控制,解决问题 . 有关更多示例,请参阅React Controlled Components .

    与此错误无关,您应该只有一个默认导出 . 你上面的代码有两个 .

  • 3

    首次渲染组件时,未设置 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 ,您的输入将始终具有值,并且该消息将消失 .

  • 1

    另一种方法是在输入中设置默认值,如下所示:

    <input name="name" type="text" value={this.state.name || ''} onChange={this.onFieldChange('name').bind(this)}/>
    
  • 22

    我知道其他人已经回答了这个问题 . 但是,这里一个非常重要的因素可能会帮助其他人遇到类似的问题:

    您必须在输入字段中添加 onChange 处理程序(例如textField,checkbox,radio等) . 并始终通过 onChange 处理程序处理活动,如:

    <input ... onChange={ this.myChangeHandler} ... />
    

    当您使用 checkbox 时,您可能需要使用 !! 来处理其 checked 状态:

    <input type="checkbox" checked={!!this.state.someValue} onChange={.....} >
    

    参考:https://github.com/facebook/react/issues/6779#issuecomment-326314716

  • 1

    如果组件上的props已作为状态传递,请为输入标记设置默认值

    <input type="text" placeholder={object.property} value={object.property ? object.property : ""}>
    
  • 70

    在初始状态下将值设置为“name”属性 .

    this.state={ name:''};
    

相关问题