React - changing an uncontrolled input

旧城冷巷雨未停 提交于 2019-11-26 18:09:50

I believe my input is controlled since it has a value.

For an input to be controlled, its value must correspond to that of a state variable.

That condition is not initially met in your example because this.state.name is not initially set. Therefore, the input is initially uncontrolled. Once the onChange handler is triggered for the first time, this.state.name gets set. At that point, the above condition is satisfied and the input is considered to be controlled. This transition from uncontrolled to controlled produces the error seen above.

By initializing this.state.name in the constructor:

e.g.

this.state = { name: '' };

the input will be controlled from the start, fixing the issue. See React Controlled Components for more examples.

Unrelated to this error, you should only have one default export. Your code above has two.

When you first render your component, this.state.name isn't set, so it evaluates to undefined, and you end up passing value={undefined} to your input.

When ReactDOM checks to see if a field is controlled, it checks to see if value != null (note that it's !=, not !==), and since undefined == null in JavaScript, it decides that it's uncontrolled.

So, when onFieldChange() is called, this.state.name is set to a string value, your input goes from being uncontrolled to being controlled.

If you do this.state = {name: ''} in your constructor, because '' != null, your input will have a value the whole time, and that message will go away.

Another approach it could be setting the default value inside your input, like this:

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

I know others have answered this already. But one of the very important factor here that may help other people experiencing similar issue:

You must need to have onChange handler added in your input field (e.g. textField, checkbox, radio, etc). And always handle activity through the onChange handler, like:

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

and when you are working with checkbox then you may need to handle its checked state with !! like:

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

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

One potential downside with setting the field value to "" (empty string) in the constructor is if the field is an optional field and is left unedited. Unless you do some massaging before posting your form, the field will be persisted to your data storage as an empty string instead of NULL.

This alternative will avoid empty strings:

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

... 

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

In my case, I was missing something really trivial.

<input value={state.myObject.inputValue} />

My state was the following when I was getting the warning:

state = {
   myObject: undefined
}

By alternating my state to reference the input of my value, my issue was solved:

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

When you use onChange={this.onFieldChange('name').bind(this)} in your input you must declare your state empty string as a value of property field.

incorrect way:

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

correct way:

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

Simple solution to resolve this problem is to set an empty value by default :

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

If the props on your component was passed as a state, put a default value for your input tags

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

Set a value to 'name' property in initial state.

this.state={ name:''};

This generally happens only when you are not controlling the value of the filed when the application started and after some event or some function fired or the state changed, you are now trying to control the value in input field.

This transition of not having control over the input and then having control over it is what causes the issue to happen in the first place.

The best way to avoid this is by declaring some value for the input in the constructor of the component. So that the input element has value from the start of the application.

An update for this. For React Hooks use const [name, setName] = useState(" ")

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!