ReactJS component from controlled to uncontrolled explained

If you don’t set initial state react will treat that as an uncontrolled component

There are a few things to note here. If you open your comment, you’ll notice two warning messages pop up immediately:

Warning: value prop on input should not be null. Consider using the empty string to clear the component or undefined for uncontrolled components.

Warning: FormPresenter contains an input of type text with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props.

Putting the jsx here for reference:

  <input 
    type="text" 
     value={this.state.value} 
     defaultValue={this.state.defaultValue}
     onChange={this.handleChange}
  />

The first warning is telling you there’s something wrong with what you’re passing as a value, and is why it gives you the error you’re asking about (more on this in a minute).

The second warning is telling you that controlled components should only use value and uncontrolled components should only use defaultValue. The reason here is if you need to set a default value for a controlled component, you can just default the value you pass to value. And if you’re using an uncontrolled component you only care about setting a default value as you want the browser to manage the current value normally.

So, now when you type in the input, it gives you that third warning:

Warning: FormPresenter is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component

This is linked to the first warning. Because you’re defaulting this.state.value to null, the input is not considered controlled. If you change the default to an empty string (''), you’re properly controlling the input and will not get the warning message.