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

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


当前回答

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

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

其他回答

当你第一次呈现你的组件时,this.state.name没有设置,所以它的值为undefined或null,你最终将value={undefined}或value={null}传递给你的输入。

当ReactDOM检查一个字段是否受控制时,它会检查value != null(注意它是!=,而不是!==),由于JavaScript中的undefined == null,它决定它是不受控制的。

因此,当onFieldChange()被调用时,this.state.name被设置为一个字符串值,你的输入从不受控制变成受控制。

如果你这样做。在你的构造函数中State = {name: "},因为" != null,你的输入将一直有一个值,并且该消息将消失。

就我而言,我错过了一些非常微不足道的东西。

<输入值= {state.myObject。inputValue} / >

当我收到警告时,我的状态如下:

state = {
   myObject: undefined
}

通过交替我的状态来引用我的值的输入,我的问题得到了解决:

state = {
   myObject: {
      inputValue: ''
   }
}

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

对于一个被控制的输入,它的值必须与状态变量的值相对应。

在您的示例中,这个条件最初没有满足,因为this.state.name最初没有设置。因此,输入最初是不受控制的。一旦onChange处理程序第一次被触发,this.state.name就会被设置。此时,上述条件满足,则认为输入是受控的。这种从不受控到受控的转变产生了上面所见的错误。

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

e.g.

this.state = { name: '' };

输入将从一开始就受到控制,从而解决问题。更多示例请参见React受控组件。

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

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

你必须有一个onChange处理程序添加在您的输入字段(例如textField,复选框,无线电等)。始终通过onChange处理程序处理活动。

例子:

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

当你使用复选框时,你可能需要用!!来处理它的选中状态。

例子:

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

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

为了动态设置表单输入的状态属性并控制它们,你可以这样做:

const inputs = [
    { name: 'email', type: 'email', placeholder: "Enter your email"},
    { name: 'password', type: 'password', placeholder: "Enter your password"},
    { name: 'passwordConfirm', type: 'password', placeholder: "Confirm your password"},
]

class Form extends Component {
  constructor(props){
    super(props)
    this.state = {} // Notice no explicit state is set in the constructor
  }

  handleChange = (e) => {
    const { name, value } = e.target;

    this.setState({
      [name]: value
    }
  }

  handleSubmit = (e) => {
    // do something
  }

  render() {
     <form onSubmit={(e) => handleSubmit(e)}>
       { inputs.length ?
         inputs.map(input => {
           const { name, placeholder, type } = input;
           const value = this.state[name] || ''; // Does it exist? If so use it, if not use an empty string

           return <input key={name}  type={type} name={name} placeholder={placeholder} value={value} onChange={this.handleChange}/>
       }) :
         null
       }
       <button type="submit" onClick={(e) => e.preventDefault }>Submit</button>
     </form>    
  }
}