如何向 React/MUI 自动完成组件添加唯一键?
How can I add unique keys to React/MUI Autocomplete component?
我正在尝试创建一个 Material-UI Autocomplete
组件,它基本上只向用户显示搜索结果。一些选项的名称会重复,但它们都有唯一的 ID。几个小时以来,我一直在尝试修复以下警告,但我无法弄清楚。
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.
我尝试在整个代码中的许多地方添加 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
可以 return 具有正确键值的列表项。您的代码抱怨重复的密钥,因为默认情况下,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,如果你把它放在callback提供的props之前:
<Box component='li' key={key} {...props}
然后它将被来自 MUI 的 props.key
覆盖。应该是这样的:
<Box component='li' {...props} key={key}
现场演示
我正在尝试创建一个 Material-UI Autocomplete
组件,它基本上只向用户显示搜索结果。一些选项的名称会重复,但它们都有唯一的 ID。几个小时以来,我一直在尝试修复以下警告,但我无法弄清楚。
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.
我尝试在整个代码中的许多地方添加 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
可以 return 具有正确键值的列表项。您的代码抱怨重复的密钥,因为默认情况下,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,如果你把它放在callback提供的props之前:
<Box component='li' key={key} {...props}
然后它将被来自 MUI 的 props.key
覆盖。应该是这样的:
<Box component='li' {...props} key={key}