React - changing an uncontrolled input

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 or null, and you end up passing value={undefined} or value={null}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.