81

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"
        />
    )}
/>
1

20 Answers 20

125

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 has 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!

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

11 Comments

@theSekyi Everytime I need to clear the Autocomplete, I change the key randomly. Mine was using momentJs.toStringISO() 🤣
this doesn't clear if you have a default value set. it resets to the default value instead. I NEED TO CLEAR!
you can use uuid as well from lodash/uniqueId
this is a bad practice i think, because you are forcing the component to rerender
@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.
|
35

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.

UPDATE: Pay attention to the current reason value types. The new values are "blur" | "clear" | "createOption" | "removeOption" | "selectOption". In this case we have to use the "clear" option.

4 Comments

And how to programmatically call this ?
Deepak Thomas, onInputChange is prop in Autocomplete, it receives function, and this function will be called when input changes
Any way to programatically do this ? Eg: On click of another button
Pay attention to the current reason value types. The new values are "blur" | "clear" | "createOption" | "removeOption" | "selectOption". In this case we have to use the "clear" option.
16

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

4 Comments

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?
umm, are you sure currVal is the correct value? try to console.log()
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.
this didn't work for me, I had to set the key as well
11

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();

1 Comment

Apparently many use this method - github.com/mui-org/material-ui/issues/…
7

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

2 Comments

I'm getting Type 'null' is not assignable to type 'NonNullable<string> | undefined'.ts(2322) for setting value to null
@ItayB I suspect you could pass undefined or '' as the value to make typescript happy in this case.
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.

Comments

1

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>

Comments

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.

Comments

1

When you want to delete the value from Autocomplete, you must set it to null, not undefined.

Ex:

good--->setValue(null)

not good--->setValue(undefined)

good--->setValue(value)

Comments

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}
...

Comments

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
        }
    })}
/>

Comments

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))],
        );
      }}

Comments

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="" />}
/>

Comments

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.

Comments

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
            }
        }}   
   />

Comments

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);
}

Comments

0

There is an easy way to do it the onInputChange has a third parameter that you can clear your input value based on that

// eventType is either input/clear/reset
// reset happens when autocomplete automatically changes the value of the input

function onInputChange(event, newValue, eventType) {
  if (eventType === 'reset') {
    setInputState('')
  }else {
    setInputState(newValue)
  }
}

<Autocomplete

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

Comments

0

If you want click on clear button and remove the value

onInputChange={(event, newInputValue, reason) => {
    if (reason === 'clear'){
      setValue('Name the Field', null or '') 
      return
    } else {
      setValue(newInputValue)
    }
  }}

1 Comment

As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
0

For anyone who is using ReactHookForm with <Controller>.

This may be working:

The key is value={availableCities.find((option) => option.id === field.value) ?? { id: 0, name: '' }}

?? { id: 0, name: '' } is just for showing and forcing it to become a controlled component. It won't be sent.

  • ie: when you click clear, the cityid will be cleared, it won't become 0.
  • ie: when you click clear, even if you have set that to ?? { id: 1230, name: 'whatever' }, it won't become 1230.
const availableCities: {
    id: number;
    name: string;
}[]

...

          <Controller
            name="homeAddress.cityid"
            control={control}
            render={({ field, fieldState }) => {
              return (
                <FormControl fullWidth>
                  <Autocomplete
                    options={availableCities}
                    getOptionLabel={(option) => option.name}
                    value={availableCities.find((option) => option.id === field.value) ?? { id: 0, name: '' }}
                    onChange={(event, option, reason) => {
                      field.onChange(option?.id);
                      // setValue('homeAddress.city', option?.name);
                    }}
                    renderInput={(params) => <TextField {...params} label="City" error={!!fieldState.error} />}
                  />
                  {fieldState.error && <FormHelperText error>{fieldState.error.message}</FormHelperText>}
                </FormControl>
              );
            }}
          />

Comments

-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.

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.