admin管理员组

文章数量:1401476

My goal is to reset the internal state of Material UI Autoplete ponent.

My custom ponent 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 Autoplete.

This is my BranchSetting ponent:

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

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 (
        <>
            <Autoplete
                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, Autoplete keep the state of the ponent ad the prev position. I'm looking a way to reset all the internal state of Autoplete ponent. The status I refer to can be seen with the devToolBar

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

My goal is to reset the internal state of Material UI Autoplete ponent.

My custom ponent 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 Autoplete.

This is my BranchSetting ponent:

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

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 (
        <>
            <Autoplete
                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, Autoplete keep the state of the ponent ad the prev position. I'm looking a way to reset all the internal state of Autoplete ponent. The status I refer to can be seen with the devToolBar

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

Share Improve this question edited yesterday Olivier Tassinari 8,6916 gold badges25 silver badges28 bronze badges asked Feb 2, 2021 at 8:57 Marco PestrinMarco Pestrin 4243 silver badges14 bronze badges 4
  • How does the branch object looks like. can you share de properties ? – Mohamed Ramrami 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 Autoplete ponent – Marco Pestrin Commented Feb 2, 2021 at 10:02
  • does it contains a unique id or unique label? – Mohamed Ramrami Commented Feb 2, 2021 at 10:04
  • @MohamedRamrami no – Marco Pestrin Commented Feb 2, 2021 at 10:10
Add a ment  | 

2 Answers 2

Reset to default 5

I resolved the problem.

The problem was that Autoplete ponent 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 Autoplete 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 pliant with the documentation were missing. So this is the new code

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

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

    const handleBrandSelected = (event, payload) => setBrands(payload);

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

    return (
        <>
            <Autoplete
                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

This problem is probably caused by using the array index as a key in <BranchSetting key={index}. I remend 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.

本文标签: javascriptMaterial UI ReactAutocompleteHow to reset the internal stateStack Overflow