如何将唯一键添加到Reaction/MUI自动完成组件?

2022-02-22 00:00:00 reactjs javascript material-ui jsx

我正在尝试创建一个Material-UIAutocomplete组件,该组件本质上只向用户显示搜索结果。一些选项的名称将是重复的,但它们都将具有唯一的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>
                            )
                        }}
                    />
                )}
            }
            
        />
    )
}

解决方案

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

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

如果仍然不起作用,请检查您的道具顺序,如果您将其放在回调提供的道具之前,则需要最后声明关键道具:

<Box component='li' key={key} {...props}
则它将被来自MUI的props.key覆盖。应该是这样的:

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

实时演示

相关文章