Unable to type in Input field issue in React [Solved]


Borislav Hadzhiev

Last updated: Apr 16, 2022


Photo from Unsplash

Unable to type in Input field issue in React [Solved] #

To solve the issue of being unable to type in an input field in React, make sure to use the defaultValue prop instead of value for uncontrolled input fields. Alternatively, set an onChange prop on the field and handle the change event.

Here is an example of how the issue occurs.

const App = () => { return ( <div> <input type="text" value="initial value" /> </div> ); }; export default App;

The problem is that the input field has a value prop set, but it doesn't have an onChange prop that handles changes of the input's value.

The easiest way to get around this is to use the onChange prop to handle the change event on the input field.

import {useState} from 'react'; const App = () => { const [message, setMessage] = useState('Initial value'); // 👇️ called every time input's value changes const handleChange = event => { setMessage(event.target.value); }; console.log(message); return ( <div> <input id="message" name="message" type="text" onChange={handleChange} value={message} /> </div> ); }; export default App;

We used the onChange prop to handle the change event on the input field. The handleChange function is invoked every time the value of the field changes.

Notice that we store the value of the input in the state.

The useState hook can be passed an initial state value.

If you don't want to use an initial state value, pass an empty string to theuseState hook, e.g. const [message, setMessage] = useState('').

Now every time the user types into the input field, the handleChange function gets called and sets a new value for the message variable, which re-renders the input field and shows the current value.

An alternative way to handle the issue where we can't type in an input is to use an uncontrolled input field.

import {useRef} from 'react'; const App = () => { const ref = useRef(null); const handleClick = () => { // 👇️ ref.current is a reference to the input field console.log(ref.current.value); }; return ( <div> <input ref={ref} id="message" name="message" defaultValue="Initial value" type="text" /> <button onClick={handleClick}>Log input value</button> </div> ); }; export default App;

The useRef() hook can be passed an initial value as an argument. The hook returns a mutable ref object whose .current property is initialized to the passed argument.

Notice that we have to access the current property on the ref object to get access to the input element on which we set the ref prop.

When we pass a ref prop to an element, e.g. <input ref={myRef} />, React sets the .current property of the ref object to the corresponding DOM node.

The useRef hook creates a plain JavaScript object, but gives you the same ref object on every render. In other words, it's pretty much a memoized object value with a .current property.

It should be noted that when you change the value of the current property of the ref, no re-renders are caused.

Now every time the user clicks on the button, the value of the input field is logged. This pattern is called uncontrolled components.

Notice that we used the defaultValue prop instead of value. The defaultValue prop allows us to specify an initial value for the input field.

If you use set the value prop on an input field, you are required to also set the onChange prop and handle the change event, otherwise you can't type in the input field.

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.