4

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.

4
  • How does the branch object looks like. can you share de properties ? Commented Feb 2, 2021 at 9:35
  • @MohamedRamrami branch is an obj with a lot of keys... the ones that interest in this case are index that is a progressive number and the array brand with all the elements I've selected in my Autocomplete component Commented Feb 2, 2021 at 10:02
  • does it contains a unique id or unique label? Commented Feb 2, 2021 at 10:04
  • @MohamedRamrami no Commented Feb 2, 2021 at 10:10

2 Answers 2

5

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
Sign up to request clarification or add additional context in comments.

Comments

0

This problem is probably caused by using the array index as a key in <BranchSetting key={index}. I recommend that you add a unique id when creating the branch object, and use that id as a key instead. You can use performance.now() or a small lib like nanoid.

You can read more about the negative impacts of using an index as a key here.

1 Comment

Hey mate! Thank you so much for your answer but there wasn't any problem with id and index. I resolved with another way. Check my answer ;)

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.