66

I have one problem in my react code.

I use Material-ui and redux-form. I have select input like and after change this select i should reset value in . I use action 'change' from react-form and set value for textfield. But label in still remains. Can i clear or reset value in ?

<Autocomplete
    options={list}
    getOptionLabel={option => option.name}
    onInputChange={onChange}
    onChange={onChangeAutoComplete}
    noOptionsText='Нет доступных вариантов'
    loadingText='Загрузка...'
    openText='Открыть'
    renderInput={params => (
        <Field
            {...params}
            label={label}
            name={fieldName}
            variant="outlined"
            fullWidth
            component={renderTextField}
            className={classes.textField}
            margin="normal"
        />
    )}
/>
Kirill
  • 661
  • 1
  • 5
  • 3

16 Answers16

105

Using hooks on the value prop breaks the functionality of the autocomplete component ( at least for me ). Using class, and setting the local state is the same.

Luckily it is a react component, so it have a "key" prop. When the key prop changes, the component is re-rendered with the default values ( which is an empty array since nothing is selected). I used hooks in the parent component and passed the values to the key prop, whenever reset is needed.

<Autocomplete
    key={somethingMeaningful} // Bool, or whatever just change it to re-render the component
//...other props
/>

Hope this helps!

Milan Neninger
  • 1,120
  • 1
  • 4
  • 7
  • @RaizalI.N.Pregnanta what did you change set your key to? – theSekyi Apr 23 '20 at 10:17
  • @MohammedTawfik are you using version 3 of material-ui? – theSekyi Apr 23 '20 at 10:17
  • 3
    @theSekyi Everytime I need to clear the Autocomplete, I change the key randomly. Mine was using momentJs.toStringISO() – Raizal I.N. Pregnanta Apr 24 '20 at 11:04
  • 3
    this doesn't clear if you have a default value set. it resets to the default value instead. I NEED TO CLEAR! – jpro Dec 24 '20 at 07:09
  • This worked for me. In my case, the key is set to a value from redux store. It is convenient for me that way since I am making an API request to reset the menu from a far away component. I am making a dispatch request to store which changes the key to a random number once I call the API endpoint – bachree Aug 12 '21 at 02:28
  • 1
    you can use uuid as well from lodash/uniqueId – Bugfixer Nov 15 '21 at 11:09
  • 2
    this is a bad practice i think, because you are forcing the component to rerender – Safi Habhab Feb 04 '22 at 11:07
  • 1
    @SafiHabhab The material ui component itself has a bug, and forcing the re-render is the solution if you want to use it as it supposed to be used. – Milan Neninger Feb 17 '22 at 09:45
  • The effective solution for my case where I was unable to reset the value or so. – webHasan Jun 14 '22 at 03:47
  • why can't we use the blurOnSelect=true option? isnt – mattsmith5 Jul 12 '22 at 04:52
  • @jpro This solution works, in my case, I needed to reset the *autocomplete* after a successful form submission. So I created a key variable with state which I increment by one every time my form submits successfully example `const [key, setKey] = useState(0)`; // on successful submit setKey(key + 1) – bishop Dec 21 '22 at 09:08
25

Material UI Autocomplete onInputChange callback provides reason argument. If input has been changed by input, reason will be input and if you selected option then reason will be reset.

onInputChange={(event, newInputValue, reason) => {
    if (reason === 'reset') {
      setValue('')
      return
    } else {
      setValue(newInputValue)
    }
  }}

setValue is useState and you can pass value state to autocomplete value property.

Cosmin Staicu
  • 1,809
  • 2
  • 20
  • 27
Scrooppi
  • 267
  • 3
  • 6
15

use value in your <Autocomplete /> like this:

<Autocomplete
    value={this.state.value} //insert your state key here
//...other props
/>

Then clear state of that key, to clear the autocomplete field value

Wasim Abuzaher
  • 804
  • 6
  • 15
  • So `onInputChange={onChange}` `onChange={onChangeAutoComplete}` update your redux store, and return a state that you map to a prop, no? using that prop in the value of `Autocomplete` still didn't work? – Wasim Abuzaher Jan 17 '20 at 16:38
  • umm, are you sure currVal is the correct value? try to console.log() – Wasim Abuzaher Jan 17 '20 at 18:24
  • yes, i tried. When i chang first select this value change and equals ''. And changed when i write in autocomplete, in this case equals that i write. – Kirill Jan 17 '20 at 18:34
  • 1
    this didn't work for me, I had to set the key as well – Steve Jan 22 '21 at 18:01
7

I am going to post a very dirty way of clearing the value of Autocomplete. Try it ONLY when nothing else works;

import React, { useRef } from 'react';
...
const autoC = useRef(null);
...
<Autocomplete
  ...
  ref={autoC}
/>

and then when you want to clear the value;

const ele = autoC.current.getElementsByClassName('MuiAutocomplete-clearIndicator')[0];
if (ele) ele.click();
Baqer Naqvi
  • 6,011
  • 3
  • 50
  • 68
  • 2
    Apparently many use this method - https://github.com/mui-org/material-ui/issues/4736#issuecomment-642444300 – gowthz Jan 24 '22 at 03:47
4

You can use something like the following to clear the autocomplete field when an item is selected.

<Autocomplete
  value={null}
  blurOnSelect={true} />

Note that you may also need to set clearOnBlur={true} if you're using the freeSolo option.

Source https://mui.com/api/autocomplete/#props

Dennis
  • 779
  • 9
  • 14
2

This is what worked for me.

const [name, setName] = useState('');

<Autocomplete
  inputValue={name}
  onChange={(e,v)=>setName(v?.name||v)}
  ...
/>
<Button onClick={()=>setName('')}>
 Clear
</Button>
prakhar tomar
  • 933
  • 1
  • 8
  • 10
1

I achieved this by updating the inputValue prop where multiple prop is false. If you are using multiple prop, then there is a propblem (bug). Selected values does not get erased.

1

When I encountered this, it was when options for the autocomplete changed, and wanted to clear the input value. It wouldn't clear with just the options changing. What worked for me is adding a key value onto the autocomplete which depended on the change which necessitated clearing.

Madeline H
  • 36
  • 2
0

To solve this, I created a hook that watches the value state of the autocomplete and set the value of the input if the checkClear returns true;

function useAutocompleteInputClear(watch, checkClear) {
    const elmRef = useRef(null);
    useMemo(() => {
            if (!elmRef || !elmRef.current) return;

            if (!checkClear || typeof checkClear !== "function") return;

            const button = elmRef.current.querySelector("button")
            if (checkClear(watch) && button) {
                button.click();
            }

    }, [watch])

    return elmRef;
}

Its first argument is the value that should be watched and its second argument is a function that returns a boolean. if it is true the clearing will happen. Also, the hook returns a ref that needs to pass as ref prop to Autocomplete.

const elmRef = useAutocompleteInputClear(value, v => !v || !v.id)

<Autocomplete ref={elmRef} 
              value={value}
...
Behnam Azimi
  • 2,260
  • 3
  • 34
  • 52
0

using onChange property we can clear the value by clicking the clear icon in the following way

<Autocomplete
    fullWidth={true}
    label={'Source'}
    margin={'noraml'}
    multiple={false}
    name={'Source'}
    getOptionSelected={useCallback((option, value) => option.value === value.value)}
    ref={SourceRef}
    value={formValues.Source === '' ? {label: ''} : {label: formValues.Source}}
    options={SourceStatus}
    onChange={useCallback((e, v) => {
        if (typeof v === 'object' && v !== null) {
            handleInputChange(e, v) // help to set the value
        } else {
            handleInputChange(e, {label: ''}) // help to reset the value
        }
    })}
/>
KARTHIKEYAN.A
  • 18,210
  • 6
  • 124
  • 133
0

In my case for multiselect freeSolo onChange props 3rd argument reason solved my all issues.

AutocompleteChangeReason can be:

  • blur
  • clear
  • createOption
  • removeOption
  • selectOption

and 2nd arg of this props gives u already updated list of (multiselect) value/s.

      onChange={(_event, newOptions, reason) => {
        setOptions(
          reason === 'clear' ? [] : [...newOptions.map((o) => Number(o))],
        );
      }}
Konrad Grzyb
  • 1,561
  • 16
  • 12
0

If you need only the selected value, set the value to an empty object and render the option to your needs.

<Autocomplete
    value={{}}
    onChange={handleSelectionChanged}
    options={options ?? []}
    getOptionLabel={x => (!x ? '' : x?.name ?? '')}
    renderInput={params => <TextField {...params} label="" />}
/>
0

If you are using objects, you can use the following code to clear the field.

Ensure you add isOptionEqualToValue:

<Autocomplete
    style={{ width: 250 }}
    multiple
    id="checkboxes-tags-demo"
    options={list}
    isOptionEqualToValue={(option, newValue) => {
        return option.id === newValue.id;
    }}
    value={selected}
    onChange={(e, val) => handleSelected(e, val)}
    getOptionLabel={(option) => option.name}
    renderInput={(params) => (
        <TextField
            {...params}
            label="Add to Multiple"
            placeholder="Favorites" />
    )} />

Just set an empty array in your state through functions, and it'll be cleared.

GROVER.
  • 4,071
  • 2
  • 19
  • 66
0

Try this method:

use onChange method and pass third parameter reason and compare to clear text if reason is clear then executed this function.

<Autocomplete
       onChange={(event, newValue, reason) => {             
            if (reason === 'clear') {
                console.log("Put your clear logic here: this condition executed when clear button clicked")
                setValue({ title: '', year: '' }) //for reset the value
                return
            }
        }}   
   />
0

I've noticed when you clear, it triggers onChange but the option is null, so you can reset your field if is a controlled input

onChange = (_, option: object | null) => {
   if(!option) setState(null);

   setState(option.value);
}
Kakiz
  • 1,145
  • 1
  • 9
  • 18
-2

One easy way to do this is to pass these props to autocomplete like this:

onChange={handleSkillChange}
inputValue=''
clearOnBlur={true}
  • onChange is an event handler, which stores the value in the state.
  • inputValue='' helps to ensure that the text field inside autocomplete will always be empty
  • clearOnBlur={true} helps to clear the value of the autocomplete component when it loses focus.
Naing Lin Aung
  • 3,373
  • 4
  • 31
  • 48