Rxjs和React状态挂钩导致多个API调用并重新渲染

时间:2020-08-01 15:54:38

标签: reactjs rxjs

我正在尝试在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)时,会得到预期的行为,即仅进行一次调用并相应地进行限制。有办法解决这个问题吗?

1 个答案:

答案 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);
  };