我正在尝试获取反应组件中输入字段的建议。我在这个输入字段上触发onChange事件,然后进行api调用并获取相关内容。
这就是我这样做的方式
<span>
<input type="text" placeholder="Add tag" list="languages" id='tags-input-field'
className={`addtag-input ${this.state.showAddTagInputArray.findIndex(x => x === item.id) !== -1 ? "" : "hidden"}`}
onChange={this.searchTags.bind(this)}
/>
<datalist id='languages'>
{this.state.existingTags && this.state.existingTags.map((item,i)=>{
return <option value= {item.name} />
})}
</datalist>
</span>
这是&#34; searchTags&#34;功能
searchTags(){
let req = fetch(url + document.getElementById("tags-input-field").value,
{
method: "GET",
headers: {
"Authorization": "Token " + this.props.token_reducer.token,
"content-type": "application/json"
}
})
req.then(response => response.json()
).then(response => {
console.log(response)
this.setState({existingTags:response})
})
}
问题:这种方法的问题是,我按下的每个字母都会触发searchTags()。假设我非常快地键入10个字母,然后10个请求开始,这就是挂起我的系统。我该如何处理这个问题?
答案 0 :(得分:1)
您可以使用setTimeout(fetch, n)
之类的内容延迟ajax请求,并在每次按键时清除超时。这导致它仅在停止输入至少n
毫秒后才进行搜索。
this.state = {
searchTimeout: false
}
searchTags(){
clearTimeout(this.state.searchTimeout);
let searchTimeout = setTimeout(function() {
let req = fetch(url + document.getElementById("tags-input-field").value,
{
method: "GET",
headers: {
"Authorization": "Token " + this.props.token_reducer.token,
"content-type": "application/json"
}
})
req.then(response => response.json()
).then(response => {
console.log(response)
this.setState({existingTags:response})
})
}.bind(this), 500);
this.setState({searchTimeout});
}
答案 1 :(得分:0)
这是搜索输入的一个非常常见的问题。涵盖常见用例的最简单的解决方案是去除呼叫。
constructor () {
this.searchTags.bind(this);
this.debouncedSearch = this.debounce(this.searchTags, 300);
}
debounce = (func, wait = 100) => {
let timeout;
return (...args) => {
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(this, args);
}, wait);
};
};
// in render
onChange={this.debouncedSearch}
Lodash还有一个很好的现成debounce。
由于您要呈现列表,因此每个列表项还需要add a key。 Don't use index as your key,选择一个唯一标识符。
<datalist id='languages'>
{this.state.existingTags && this.state.existingTags.map((item,i)=>{
return <option key={item.id} value= {item.name} />
})}
</datalist>