React warning component is changing an uncontrolled input to be controlled

Last updated : May 7, 2023

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.

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:

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.

<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.
    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.
    <input type="text" defaultValue={value} onChange={handleChange} />
L Raney
By: L Raney
Lance is a software engineer with over 15 years of experience in full-stack software development.
Read more...

Comments are disabled

No Comments