Monday, May 13, 2024
 Popular · Latest · Hot · Upcoming
167
rated 0 times [  170] [ 3]  / answers: 1 / hits: 23383  / 3 Years ago, thu, september 30, 2021, 12:00:00

I'm trying to create a Material-UI Autocomplete component that essentially just displays search results to the user. Some of the options' names will be duplicates, but they will all have unique IDs. I receive the following warning:



index.js:1 Warning: Encountered two children with the same key, Name B. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.



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>
)
}}
/>
)}
}

/>
)
}

More From » reactjs

 Answers
93

You can define your own renderOption that can return the list item with a correct key value. Your code complains about the duplicated keys because by default, Autocomplete uses the getOptionLabel(option) to retrieve the key:


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

If it still doesn't work, check your props order, you need to declare the key prop last, if you put it before the props provided by the callback:


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

Then it will be overridden by the props.key from MUI. It should be like this:


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

Live Demo


Codesandbox


[#50160] Monday, September 6, 2021, 3 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
kylanalis

Total Points: 438
Total Questions: 85
Total Answers: 102

Location: Barbados
Member since Sun, Nov 27, 2022
1 Year ago
kylanalis questions
Sat, Oct 2, 21, 00:00, 3 Years ago
Tue, Oct 13, 20, 00:00, 4 Years ago
Thu, Feb 13, 20, 00:00, 4 Years ago
Tue, Jan 7, 20, 00:00, 4 Years ago
;