You provided 'value' prop to a form field without onChange handler

avatar

Borislav Hadzhiev

Wed Apr 06 20222 min read

You provided 'value' prop to a form field without onChange handler #

The error "You provided a value prop to a form field without an onChange handler" occurs when we set a value prop on a field that has no onChange handler. To solve the error, use the defaultValue prop or set an onChange prop on the field.

you provided value prop to form field

Here is an example of how the error occurs.

App.js
export default function App() { // ⛔️ You provided a `value` prop to a form field // without an `onChange` handler. This will render // a read-only field. If the field should be mutable // use `defaultValue`. Otherwise, set either `onChange` or `readOnly`. return ( <div> <input type="text" id="message" value="Initial value" /> </div> ); }

The issue in the code sample above is that we've set the value prop on the input field without providing an onChange event handler. This makes the input's value static.

One way to solve the error is to use the defaultValue prop instead.

App.js
export default function App() { return ( <div> <input type="text" id="message" defaultValue="Initial value" /> </div> ); }

The defaultValue prop sets an initial value for the input field, but the value is not static and can be changed.

The defaultValue prop is often used for uncontrolled (by the developer) fields. This means that you would have to access the value of the input field using a ref or as an element in a form.
App.js
import {useRef} from 'react'; // 👇️ Example of uncontrolled input field export default function App() { const ref = useRef(null); const handleClick = () => { console.log(ref.current.value); }; return ( <div> <input ref={ref} type="text" id="message" defaultValue="Initial value" /> <button onClick={handleClick}>Click</button> </div> ); }

Every time you click on the button, the value of the input field will be logged to the console.

Alternatively, we can set an onChange prop on the input field and handle the event.

App.js
import {useState} from 'react'; export default function App() { const [message, setMessage] = useState(''); const handleChange = event => { setMessage(event.target.value); // 👇️ this is the input field itself console.log(event.target); // 👇️ this is the new value of the input console.log(event.target.value); }; return ( <div> <input type="text" id="message" placeholder="Your message" onChange={handleChange} value={message} /> </div> ); }

The first thing we did is store the input value in a state variable called message.

We set the onChange prop on the input field, so every time the input's value is changed, the handleChange function is invoked.

We can access the input field via the target property on the event object.

Similarly, we can access the input's value via event.target.value.

If you want to provide an initial value for the input, you can just pass it to the useState() hook.

App.js
import {useState} from 'react'; export default function App() { // 👇️ set initial value in call to useState const [message, setMessage] = useState('Your initial value'); const handleChange = event => { setMessage(event.target.value); console.log(event.target.value); }; return ( <div> <input type="text" id="message" placeholder="Your message" onChange={handleChange} value={message} /> </div> ); }

The string we passed to the useState hook will be set as the initial value for the message variable.

Use the search field on my Home Page to filter through my more than 1,000 articles.