16

I'm using Google maps address autocomplete in my React app. It works by hooking into an input element, watching for changes, and providing a dropdown location select.

Relevant code:

<InputGroup hasValidation className="mb-3">
    <FormControl id="autocomplete"/>
</InputGroup>
useEffect(() => {
        
    // only specify the fields we need, to minimize billing
    const options = {"fields": ["address_components"]}

    const autocompleteElement = document.getElementById("autocomplete")

    if(autocompleteElement) {

        autocomplete.current = new google.maps.places.Autocomplete(autocompleteElement, options);
            
        const listener = autocomplete.current.addListener("place_changed", placeSelected);
        return function cleanUp() {
            google.maps.event.clearInstanceListeners(listener);
        }
    } else {
        // nothing to do yet
        return;
    }
});

However, I'm getting a warning in the browser console:

Warning: A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component

Seems obvious enough- the autocomplete functionality is changing the input itself as opposed to using react state to make a controlled component. However that's the way I want it. Is there a way I can silence this error? I've tried adding an empty defaultValue and an empty onChange function, but still got the error. Thanks in advance!

(There were a few questions with the same issue, but nothing about deliberately disabling the warning)

4
  • 1
    Have you tried adding value="" yet? Commented Apr 11, 2022 at 22:53
  • Sooo, any news? Just curious, cause I'd like to close the tab ;) Commented Apr 12, 2022 at 11:20
  • @ChrisG Heh, sorry to keep your tabs open. value="" makes it so that I can't type in the field. I also tried going all the way and setting up state and value and onChange attributes, and that doesn't work either. Commented Apr 12, 2022 at 18:17
  • Does this answer your question? A component is changing an uncontrolled input of type text to be controlled error in ReactJS Commented Mar 11, 2024 at 22:27

7 Answers 7

19

I have faced such warnings on a couple of projects here is one of the causes and solution.

const [value, setValue] = useState("");
<input value={value} onChange={inputHandler} />

From the code above notice that the state initial value is "", check yours. Its possible you are using null or empty value.

You need to change it to empty string and that warning will disappear.

Let me know if its helpful.

Sign up to request clarification or add additional context in comments.

1 Comment

This worked for me as a start point. I have a nullable string being returned from a service and the typescript model did not have a corresponding nullable property. Changed the return to an empty string and bam, warning gone.
9

We cleared this error by simply adding default values to our form inputs:

<p style={{ fontWeight: 'bold' }}>Devices: </p>{' '}
<Select
    isMulti
    value={mapValuesToSelect(devices) || []}
    //       this one rigth here      ^^^^^ 
    onChange={(e) => editDevicesMultiSelect(e)}

or simple input:

<Input
    type="text"
    value={code || ''}
    //          ^^^^^

P.S. we also have a handleSelectOnClose function:

<Button onClick={handleUnselect}>
    CLOSE
</Button>
const handleUnselect = () => {
    dispatch(setCurrentDesk(undefined));
};

Comments

2

Use a regular uncontrolled html input instead of one of the controlled react-bootstrap inputs.
You can use a ref to refer to the input.

<InputGroup hasValidation className="mb-3">
   <input
          defaultValue="Belgium"
          type="text"
          ref={this.autocomplete} />
</InputGroup>

More info on uncontrolled inputs and ref usage here:
https://reactjs.org/docs/uncontrolled-components.html

2 Comments

I tried this after you suggested it, but I'm still getting the same error. I tried with and without a ref. I also tried using a normal <input> with a value and onChange, but that doesn't seem to word either.
Can you share your updated code that uses the input directly ?
2
+200

You can try using a third party custom package like: React Places autocomplete. This package provides an option to use controlled input, as well as other props to customise styling and other methods

const [value, setValue] = useState(null);
<GooglePlacesAutocomplete
  selectProps={{
    value,
    onChange: setValue,
  }}
/>

Comments

1

You need to give an initial value and an onChange method. I'd probably use a hook to make this easier to manage. You could then use the useEffect() hook to call the API when the value of inputText changes.

const [inputText, setInputText] = useState('');

useEffect(() => {
    if (inputText.length > 0) {
        ... call the api
    }
},[inputText])

<InputGroup hasValidation className="mb-3">
    <FormControl id="autocomplete" value={inputText} onChange={(event) => {setInputText(event.target.value}}/>
</InputGroup>

Comments

0

as Blessing Ladejobi said its beacuse of

<input value={myValue} onChange={inputHandler} /> and myValue=null

solution is define a default value for myValue (like myValue="")

Comments

0

I tried this way in case that email is about to enter.

const onChangeEmail = (e) => setEmail(e.target.value);

and then input tag,

input type="email" value={email} onChange={onChangeEmail}

So, onChangeEmail is controlled.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.