如何向 React/MUI 自动完成组件添加唯一键?

Posted

技术标签:

【中文标题】如何向 React/MUI 自动完成组件添加唯一键?【英文标题】:How can I add unique keys to React/MUI Autocomplete component? 【发布时间】:2021-11-22 12:22:07 【问题描述】:

我正在尝试创建一个 Material-UI Autocomplete 组件,它本质上只是向用户显示搜索结果。一些选项的名称会重复,但它们都有唯一的 ID。几个小时以来,我一直在尝试修复以下警告,但我无法弄清楚。

index.js:1 警告:遇到两个具有相同键的孩子,Name B。密钥应该是唯一的,以便组件在更新时保持其身份。非唯一键可能会导致子项重复和/或省略 - 该行为不受支持,并且可能会在未来版本中更改。

我尝试在代码中的许多地方添加key=,但均无济于事。

代码附在下面,我对此很陌生,因此也欢迎任何有关如何改进其余代码的建议。

const SearchField = () => 
    const [open, setOpen] = React.useState(false)
    const [searchQuery, setSearchQuery] = React.useState('')
    const [searchResults, setSearchResults] = React.useState([])
    const loading = true //later

    const debounced = useDebouncedCallback(
        async searchQuery => 
            if (searchQuery) 
                let result = await doSearch(searchQuery)
                if (result.status === 200) 
                    setSearchResults(result.data)
                 else 
                    console.error(result)
                
            
        ,
        1000
    )

    const handleInputChange = e => 
        if (e.target.value && e.target.value !== searchQuery) 
            debounced(e.target.value)
            setSearchQuery(e.target.value)
        
    

    const options = [
        name: 'Name A',
        id: 'entry_0597856'
    ,
        name: 'Name B',
        id: 'entry_3049854'
    ,
        name: 'Name B',
        id: 'entry_3794654'
    ,
        name: 'Name C',
        id: 'entry_9087345'
    ]


    return (
        <Autocomplete
            id='search_freesolo'
            freeSolo
            selectOnFocus
            clearOnBlur
            handleHomeEndKeys
            autoHighlight
            onInputChange=handleInputChange
            open=true
            onOpen=() => setOpen(true)
            onClose=() => setOpen(false)
            loading=loading
            key=option => option.id

            options=options
            getOptionLabel=option => option.name

            renderOption=(props, option) => (
                <Box
                    component='li'
                    ...props
                >
                    option.name
                </Box>
            )

            renderInput=params => 
                return (
                    <TextField
                        ...params
                        required
                        id="search_bar"
                        label="Search"
                        InputProps=
                            ...params.InputProps,
                            endAdornment: (
                                <React.Fragment>
                                    loading ? <CircularProgress size=18 /> : null
                                    params.InputProps.endAdornment
                                </React.Fragment>
                            )
                        
                    />
                )
            
            
        />
    )

【问题讨论】:

【参考方案1】:

您可以定义自己的renderOption,它可以返回具有正确键值的列表项。您的代码抱怨重复的密钥,因为默认情况下,Autocomplete uses the getOptionLabel(option) 检索密钥:

<Autocomplete
  renderOption=(props, option) => 
    return (
      <li ...props key=option.id>
        option.name
      </li>
    );
  
  renderInput=(params) => <TextField ...params label="Movie" />
/>

如果还是不行,检查你的props顺序,如果你把key prop放在回调提供的props之前,你需要最后声明:

<Box component='li' key=key ...props

然后它将被 MUI 中的 props.key 覆盖。应该是这样的:

<Box component='li' ...props key=key

现场演示

【讨论】:

这行得通,谢谢,但是我希望稍后在 中添加一些可能无法正常工作的其他内容(例如图标、括号中的日期等)。我认为我可以只添加一个带有 key=option.id 的 div 或 span ,但这样我可以更好地理解 - 我的原始代码有什么问题?为什么即使我将 key=option.id 添加到 中, 也能正常工作,而 却不能?谢谢 @kougami 它与Box 配合得很好,我已经为你更新了现场演示。我使用li 仅用于演示目的(更简单的代码,更易于理解)。 恐怕它对我来说不是那样工作 - 当我使用 时,option.name 似乎被用于钥匙。我可以在演示中看到它的工作原理,但是如果我没记错的话,演示中的代码只是来自 MUI 文档,而不是我自己的代码? @kougami 你需要最后声明key 属性,如果你把它放在回调提供的props 之前,比如&lt;Box component='li' key= ...props,那么它将被来自MUI 的props.key 覆盖. 这太疯狂了,事情就是这么简单。但是现在我学到了一些东西,我以后会把 ...props 放在第一位!非常感谢您的帮助和帮助我理解。

以上是关于如何向 React/MUI 自动完成组件添加唯一键?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React MUI <Menu /> 组件上制作方向 rtl?

TypeScript 错误 - React mui MenuItem 上不存在属性组件

如何在反应 js 中使用 uuid 添加唯一键?

React组件渲染

如何通过向它们添加组件来使滚动器内的视图自动调整大小? - 斯威夫特 3

如何向 NetBeans 添加新的 Java 组件?