我正在尝试使用语义UI和React创建一个多选下拉列表,该下拉列表可从API动态获取数据。它成功地获取了数据,但是当我再次搜索相同的数据时,它将其重新添加到选项列表中,并且出现“两个具有相同键的子代”控制台错误。
我添加了一个排除语句“ if(!this.state.options.includes(e))”,但显然这无济于事。
[我也试图遍历当前接收到的数据和先前的状态,并使ID相互匹配,以防止填充相同的值,但是这种策略也很不走运。
getOptions = () => {
if(this.state.searchQuery) {
this.setState({isFetching:true})
axios.get('URL', {
params: {
query: this.state.searchQuery,
api_key: KEY
}
})
.then( (response) => {
this.setState((prevState)=>({
options: [
...response.data.results.map( (e) => {
if (!this.state.options.includes(e)) {
return {
key: e.id,
text: e.name,
value: e.id
}
}
})
, ...prevState.options]
}), () => this.setState({isFetching:false}))
}).catch(function () {
return
})
}
}
handleChange = (e, { value }) => {this.setState({ value })}
handleSearchChange = (e, { searchQuery }) => {
this.setState({ searchQuery }, () => {this.getOptions()}
)}
render() {
const { options, isFetching, search, value } = this.state
return (
<Grid>
<Grid.Column width={5}>
<Dropdown
fluid
onAddItem={this.handleAddition}
selection
multiple
search={search}
options={options}
value={value}
placeholder="Search keywords"
onChange={this.handleChange}
onSearchChange={this.handleSearchChange}
disabled={isFetching}
loading={isFetching}
/>
</Grid.Column>
</Grid>
)
}
当我再次搜索相同数据时,我不希望选项菜单将相同的搜索结果添加到已经存在的选项列表中。
更新了此答案,因为我认为问题是您的map
原样将返回具有所需信息的对象,否则将不返回任何内容。在后一种情况下,该元素将不会被删除,只会被取消定义。请尝试以下操作,该操作分两个步骤执行:将结果过滤为仅唯一结果,然后仅使用那些唯一值进行状态设置。
const unique = response.data.results.filter(e => {
return !this.state.options.some(el => el.id === e.id);
});
this.setState(prevState => ({
options: [
...unique.map(e => ({
key: e.id,
text: e.name,
value: e.id
}),
...prevState.options
]
}));
这可能不是一种超级有效的检查方法,因为您可能要遍历许多现有结果。如果遇到性能问题,可以考虑将搜索结果作为对象进行维护,或使用类似Set
的方法来获得哈希表查找效率。