React warning component is changing an uncontrolled input to be controlled

Last updated : Jul 30, 2023 12:00 AM

In React, a controlled input is an input element whose value is controlled by React through the use of state. Therefore, an input should have a value that is not undefined or null to be a valid, controlled input.

Figure 1: Warning component is changing an uncontrolled input to be controlled
Figure 1: Warning component is changing an uncontrolled input to be controlled

This warning can happen if the state variable that holds the initial input value is undefined or null. Therefore, the input element will be uncontrolled when the component renders for the first time. However, when the state is updated to a non-null or non-undefined value, the input element becomes controlled, which triggers the warning.

Here is an example:

Uncontrolled inputDescription
import { useEffect, useState } from "react"

export const TextInput = (props) => {
   {/*This state variable is undefined when renders for the first time*/}
    const [value, setValue] = useState();

    const handleChange = (event) => {
      setValue(event.target.value)
    }
    return (
      <div>
        {/* This input starts as uncontrolled because the value is undefined */}
        <input type="text" value={value} onChange={handleChange} />
  
        {/* Later on, the state value is updated to a non-null value */}
        {value && <p>Value is {value}</p>}
      </div>
    )
}

As you can see, the state variable value is undefined when the component is rendered for the first time. That results in the input element rendering like the one below.

Rendered as an undefined inputDescription
<input type="text" value onChange={handleChange} />

Now that is an uncontrolled input.

But soon after you type something into the input, the state value is updated, and the input value becomes defined. That makes the input a controlled input.

How to fix this warning?

To fix this warning, you should ensure the input element is always controlled or uncontrolled and not switch between the two during the component's lifecycle.

  1. If you want to use state to manage the input's value, ensure the initial state value is always non-null or non-undefined. It is simple as assigning a default value to the state variable. Then the input will remain as a controlled input.
    Assign default valueDescription
    const [value, setValue] = useState("")
  2. The other option is to use a defaultValue or defaultChecked attribute instead of the value attribute to initialize the input's value. It is important to note that this will make the input uncontrolled, which may or may not be appropriate for your use case. The state variable value can remain as undefined.
    Using defaultValueDescription
    <input type="text" defaultValue={value} onChange={handleChange} />
Lance

By: Lance

Hi, I'm Lance Raney, a dedicated Fullstack Developer based in Oklahoma with over 15 years of exp

Read more...