Fix - A component is changing an uncontrolled input to be controlled

avatar

Borislav Hadzhiev

Last updated: Apr 19, 2022

banner

Check out my new book

Fix - A component is changing an uncontrolled input to be controlled #

The warning "A component is changing an uncontrolled input to be controlled" occurs when an input value is initialized to undefined but is later changed to a different value. To fix the warning, initialize the input value to an empty string, e.g. value={message || ''}.

component changing uncontrolled input

Here is an example of how the error occurs.

App.js
import {useState} from 'react'; const App = () => { // 👇️ didn't provide an initial value for message const [message, setMessage] = useState(); const handleChange = event => { setMessage(event.target.value); }; return ( <div> <input type="text" id="message" name="message" onChange={handleChange} value={message} /> </div> ); }; export default App;

The issue in the code sample is that the message state variable is initially set to undefined, because we didn't pass an initial value for it to the useState hook.

One way to solve the error is to provide a fallback if the input value is undefined.

App.js
import {useState} from 'react'; const App = () => { const [message, setMessage] = useState(); const handleChange = event => { setMessage(event.target.value); }; // 👇️ value={message || ''} return ( <div> <input type="text" id="message" name="message" onChange={handleChange} value={message || ''} /> </div> ); }; export default App;

We used the logical OR (||) operator, which returns the value to the right if the value to the left is falsy (e.g. undefined).

If the message variable stores an undefined value, we return an empty string as a fallback.

An alternative solution is to pass an initial value for the state variable to the useState hook.

App.js
import {useState} from 'react'; const App = () => { // 👇️ pass an initial value to the useState hook const [message, setMessage] = useState(''); const handleChange = event => { setMessage(event.target.value); }; return ( <div> <input type="text" id="message" name="message" onChange={handleChange} value={message} /> </div> ); }; export default App;

Passing an initial value to the useState hook gets rid of the warning because now the message variable doesn't change from undefined to having a value.

The warning is caused because when the message variable is initialized without a value, it is set to undefined.

Passing a prop like value={undefined} is the same as not passing the value prop at all.

Once the user starts typing in the input, the value prop is now passed to the input field and the input changes from uncontrolled to controlled, which is not allowed.

Note that if you use an uncontrolled input field, you should use the defaultValue prop instead of value.

App.js
import {useRef} from 'react'; const App = () => { const inputRef = useRef(null); function handleClick() { console.log(inputRef.current.value); } return ( <div> <input ref={inputRef} type="text" id="message" name="message" defaultValue="Initial value" /> <button onClick={handleClick}>Log message</button> </div> ); }; export default App;

uncontrolled input default value

The example above uses an uncontrolled input. Notice that the input field does not have an onChange prop or value set.

You can pass an initial value to an uncontrolled input with the defaultValue prop. However, this is not necessary and you can omit the prop if you don't want to set an initial value.

When using uncontrolled input fields, we access the input using a ref.

Every time the user clicks on the button in the example, the value of the uncontrolled input gets logged.

You shouldn't set the value prop on an uncontrolled input (an input field that doesn't have an onChange handler) because that would make the input field immutable and you wouldn't be able to type in it.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.