javascriptreactjsreduxmaterial-uimui-autocomplete

Material UI React - Autocomplete - How to reset the internal state


My goal is to reset the internal state of Material UI Autocomplete component.

My custom component is rendered N times in my cycle

{branches.map((branch, index) => {
    return (
        <BranchSetting
            key={index}
            index={index}
            data={branch}
            removeBranch={removeBranch}
        />

    )
})}

branch is my hook state.

This is my removeBranch function:

const removeBranch = (index) => {
    let listBranch = branches;
    listBranch.splice(index, 1);
    setBranches([...listBranch]);
}

Every time I delete an item to my array branch, everything works fine except the Autocomplete.

This is my BranchSetting component:

import React, { useState, useEffect } from "react";
import Autocomplete from '@material-ui/lab/Autocomplete';

const BranchSettings = ({ removeBranch, index, branchModify, data }) => {
    const [ brands, setBrands ] = useState(data.brands);

    const handleBrandSelected = (event, payload) => {
        const values = payload.map(item => item.value);
        setBrands(values);
    }

    useEffect(() => {
        setBrands(data.brands);
    }, [data])

    return (
        <>
            <Autocomplete
                id={'branch-brand'}
                multiple
                disableCloseOnSelect
                options={carsBrand}
                getOptionLabel={(carsBrand) => carsBrand.label}
                onChange={handleBrandSelected}
                renderTags={(value, getTagProps) =>
                    value.map((option, index) => (
                        <Chip
                            variant="outlined"
                            label={option.value}
                            size="small"
                            {...getTagProps({ index })}
                        />
                    ))
                }
                renderInput={(params) => {
                    return (
                        <TextField
                            {...params}
                            variant="filled"
                            fullWidth
                            label={'brand'}
                        />
                    )
                }}    
            />
        </>
    )
}
export default BranchSettings

carsBrand it is my data source that in the example I avoided writing the population. It's an array

Everytime I try to delete an item, Autocomplete keep the state of the component ad the prev position. I'm looking a way to reset all the internal state of Autocomplete component. The status I refer to can be seen with the devToolBar

enter image description here

I'm looking a good way to keep the items selected properly or that every time the component has changed, rerender the Autocomplete component.


Solution

  • I resolved the problem.

    The problem was that Autocomplete component need to input an array of objects with label and value keys.

    In the function handleBrandSelected I saved into my brands status just the value. I should have saved the whole object because then it must be sent as input in Autocomplete with the props value. And to handle the object I should have also used props getOptionSelected.

    No problems with the remove function, and no problems with indexes. Only the values selected in inputs and compliant with the documentation were missing. So this is the new code

    import React, { useState, useEffect } from "react";
    import Autocomplete from '@material-ui/lab/Autocomplete';
    
    const BranchSettings = ({ removeBranch, index, branchModify, data }) => {
        const [ brands, setBrands ] = useState(data.brands);
    
        const handleBrandSelected = (event, payload) => setBrands(payload);
    
        useEffect(() => {
            setBrands(data.brands);
        }, [data])
    
        return (
            <>
                <Autocomplete
                    id={'branch-brand'}
                    multiple
                    disableCloseOnSelect
                    options={carsBrand}
                    getOptionLabel={(carsBrand) => carsBrand.label}
                    onChange={handleBrandSelected}
                    renderTags={(value, getTagProps) =>
                        value.map((option, index) => (
                            <Chip
                                variant="outlined"
                                label={option.value}
                                size="small"
                                {...getTagProps({ index })}
                            />
                        ))
                    }
                    renderInput={(params) => {
                        return (
                            <TextField
                                {...params}
                                variant="filled"
                                fullWidth
                                label={'brand'}
                            />
                        )
                    }}
                    getOptionSelected={(option, value) => option.value === value.value}
                    value={brands}  
                />
            </>
        )
    }
    export default BranchSettings