我正在尝试在React中实现一个使用RxJ的简单搜索框。设计很简单,如何向api发出请求的主要逻辑如下:
export class SeachService {
constructor() {
this.searchTerm = new Subject();
}
search(term) {
this.searchTerm.next(term.value);
}
doSearch(term) {
let promise = api.business.searchByCompany(term);
return Observable.fromPromise(promise);
}
getResults() {
return this.searchTerm
.debounceTime(300)
.distinctUntilChanged()
.switchMap((term) => (term ? this.doSearch(term) : Observable.of([])))
.map((response) => {
return {
details: response,
result_hash: Date.now(),
};
})
.distinctUntilChanged((a, b) => a.result_hash === b.result_hash)
.catch((error) => {
console.error(error);
return Observable.of([]);
});
}
}
我在React组件中将其用作:
useLayoutEffect(() => {
const subscription = searchService
.getResults()
.subscribe((res) => setBusinessResults(res.details));
});
但是,这导致对该API进行多次ajax调用,就好像该组件多次重新渲染一样。当我使用简单的console.log(res.details)
时,会得到预期的行为,即仅进行一次调用并相应地进行限制。有办法解决这个问题吗?
答案 0 :(得分:0)
您可以在此处处理多个API调用。仅当用户输入的间隔为2秒时,您的API才会调用。
/**
* Handle Timeouts
*/
timeouts = {
term_name: null,
};
/**
* Search Term
*
* @param {String} name
*/
searchTerm = name => {
if (this.timeouts.term_name) {
clearTimeout(this.timeouts.term_name);
}
this.timeouts.term_name = setTimeout(() => {
this.searchTerm(); // Here you can call api it will trigger only if user has a gap of 2 seconds in his input
}, 2000);
};