我有一个简单的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


当前回答

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

不正确的方法:

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

正确的方法:

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

其他回答

只需创建一个回退到“if this.state.name为空”。

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

这也适用于useState变量。

这是一个更新。对于React Hooks使用const [name, setName] = useState(" ")

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

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>    
  }
}

解决这个问题的简单方法是在默认情况下设置一个空值:

<input name='myInput' value={this.state.myInput || ''} onChange={this.handleChange} />

在构造函数中将字段值设置为“”(空字符串)的一个潜在缺点是,如果该字段是一个可选字段,并且未被编辑。除非在发布表单之前做一些处理,否则该字段将作为空字符串持久化到数据存储中,而不是NULL。

这个选项将避免空字符串:

constructor(props) {
    super(props);
    this.state = {
        name: null
    }
}

... 

<input name="name" type="text" value={this.state.name || ''}/>