Fixing Uncontrolled to Controlled Input in React

November, 26th 2023 2 min read

React shows this warning when an input starts uncontrolled (no value) and later becomes controlled (receives a value from state). This usually happens when the state starts as undefined or null.

Why the Warning Happens

An uncontrolled input manages its own value in the DOM.
A controlled input gets its value from React state.

If the value switches between these two modes, React warns you because it can create unpredictable behavior.

Common example that triggers the warning:

jsx
const Input = ({ isChecked, setIsChecked }) => {
  return (
    <input
      type="checkbox"
      checked={isChecked}   // isChecked is undefined first render
      onChange={setIsChecked}
    />
  );
};

Because isChecked is undefined, the input is uncontrolled. After state updates, React tries to control it—triggering the warning.


How to Fix It

1. Always Provide a Default Value

Make sure your state is initialized:

jsx
const [isChecked, setIsChecked] = useState(false);

Or use a safe fallback:

jsx
<input
  type="checkbox"
  checked={isChecked ?? false}
  onChange={setIsChecked}
/>

2. Don’t Allow State to Become null or undefined

Avoid:

js
setIsChecked(undefined);
setIsChecked(null);

Always maintain the correct value type for your input.


3. Fixing Text Inputs

Incorrect:

jsx
const [value, setValue] = useState();

<input value={value} onChange={e => setValue(e.target.value)} />

Correct:

jsx
const [value, setValue] = useState("");

<input value={value} onChange={e => setValue(e.target.value)} />

Safe Conditional Rendering

jsx
<input
  value={value != null ? value : ""}
  onChange={e => setValue(e.target.value)}
/>

Summary

To eliminate this warning:

  • Always initialize state ("", false, {}, etc.)
  • Never set input state to null or undefined
  • Ensure your input is consistently controlled

This keeps your React forms stable and predictable.