The error “A component is changing an uncontrolled input to be controlled“ in React happens when you initiate an input value. Then it will be set to ‘undefined’ before the change. So how to solve it? Let’s go into detail.
The reason for this error
Example of how error happens:
import { useState } from "react"; import "./App.css"; function App() { const [name, setName] = useState(); const handleInput = (e) => { setName(e.target.value); }; return ( <div className="App"> <input type={"text"} onChange={handleInput} value={name}></input> </div> ); } export default App;
Here I initial a useState
, but I haven’t passed in the initial value so that the name
variable will be set to ‘undefined’. With the handleInput
function, setName
will set the value of the name
to input value every time I enter the value. It is not allowed in React so it leads to a warning.
Error:
How to fix the error “A component is changing an uncontrolled input to be controlled”?
Solution 1: Initial input value with an empty string
If we pass in an empty string when we initial value, its value will be an empty string instead of ‘undefined’.
Example:
import { useState } from "react"; import "./App.css"; function App() { const [name, setName] = useState(""); // <--- Initial with a empty string const handleInput = (e) => { setName(e.target.value); }; return ( <div className="App"> <input type={"text"} onChange={handleInput} value={name}></input> </div> ); } export default App;
Solution 2: Use the nullish coalescing operator ‘??’
Nullish coalescing operator ‘??’ will check for you if the left side is ‘undefined’ or ‘null’, then the right side will be returned.
Example code:
import { useState } from "react"; import "./App.css"; function App() { const [name, setName] = useState(); // <--- Initial with a empty string const handleInput = (e) => { setName(e.target.value); }; return ( <div className="App"> <input type={"text"} onChange={handleInput} value={name ?? ""}></input> </div> ); } export default App;
Solution 3: Use logical OR ‘||’
Logical OR ‘||’ have the same logic with nullish coalescing operator ‘??’ but check not only ‘undefined’ or ‘null’ but also all falsy values.
Example:
import { useState } from "react"; import "./App.css"; function App() { const [name, setName] = useState(); // <--- Initial with a empty string const handleInput = (e) => { setName(e.target.value); }; return ( <div className="App"> <input type={"text"} onChange={handleInput} value={name || ""}></input> </div> ); } export default App;
Summary
In this tutorial, I have explained how to solve the error “A component is changing an uncontrolled input to be controlled”. You can pass in an empty string when the initial value; use guard value by using the nullish coalescing operator ‘??’ or logical OR ‘||’ to check if the value is ‘undefined’.
Maybe you are interested:
- useNavigate() may be used only in the context of a Router component
- useRoutes() may be used only in the context of Router component
- Conditionally add attributes to React components
- Module not found: can’t resolve ‘#’ error in react
- Attempted import error ‘#’ is not exported from
- React Native build error: Undefined symbols for architecture x86_64

Hello, guys! I hope that my knowledge in HTML, CSS, JavaScript, TypeScript, NodeJS, ReactJS, MongoDB, Python, MySQL, and npm computer languages may be of use to you. I’m Brent Johnson, a software developer.
Name of the university: HOU
Major: IT
Programming Languages: HTML, CSS, JavaScript, TypeScript, NodeJS, ReactJS, MongoDB, PyThon, MySQL, npm