Short answer
Make value a string from the first render. Start the state as '' instead of undefined, or write value={field ?? ''} where the data may be missing. For a checkbox, keep checked a boolean with checked={done ?? false}. The reverse warning, changing a controlled input to be uncontrolled, means the value went from a string back to undefined, often after a form reset that set a field to undefined.
Where the undefined value comes from, and the fix
01
State that starts as undefined
“A controlled component should always receive a string value, not null or undefined.” React, <input>
useState() with no argument, or a form object without every field, gives the input undefined on the first render. Give each field an empty string as its starting value.
// warns: email is undefined at first const [email, setEmail] = useState(); // works: always a string const [email, setEmail] = useState(''); <input value={email} onChange={(e) => setEmail(e.target.value)} />02
Data from an API or database that arrives later
“You cannot pass value={undefined} first and later pass value="some string" because React won’t know whether you want the component to be uncontrolled or controlled.” React, <input>
A form filled from a fetch, Firestore or Supabase row has undefined fields until the response comes in, and null for empty columns after it. Fall back to an empty string where the value is read. A value of null also gets its own warning, value prop on input should not be null. With react-hook-form or Formik, give every field a starting value in defaultValues or initialValues.
<input value={profile?.phone ?? ''} onChange={(e) => setProfile({ ...profile, phone: e.target.value })} />03
A checkbox whose checked is undefined
“Similarly, if you pass checked to a checkbox, ensure it’s always a boolean.” React, <input>
checked={item.done} on an item without a done field is undefined until it is set. Use checked={item.done ?? false}, or !!item.done, so it is always true or false.
04
Mixing value and defaultValue
“An input can’t be both controlled and uncontrolled at the same time.” React, <input>
Pick one mode per input. Use value with onChange when your code needs the text as the user types, or defaultValue with no value when you only read it on submit. Switching between the two triggers this warning; passing both on one input triggers a related one.
Checked against the vendor’s docs on : React reference: <input> (troubleshooting the controlled input warning).
Rather hand it over?
Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.
- from $450App Fix TicketOne reproducible bug in an existing mobile or web app, diagnosed and fixed.See scope and start
- from $450AI-Built App RescueA Lovable, Bolt or Cursor app checked end to end in 3 days, then its worst problems fixed at a fixed price.No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.See scope and start
Related: React “Rendered more hooks than during the previous render” · React “Too many re-renders” · React “Each child in a list should have a unique key”