4

意图:

我正在尝试实现一个理想的搜索字段,直到:

  1. 已达到350ms的去抖时间
  2. AND 直到输入字段的值发生变化。

到目前为止我已经尝试过:

我使用主题来跟踪输入字段中的更改。每次输入字段发生变化handleSuggestionsFetchRequested并被调用时,我都会将一个新值向下推到SubjectusingsearchString$.next(userInput);

useEffect钩子中,我正在pipe使用searchString$withdebounceTime(350)distinctUntilChanged()。像这样的东西:

useEffect(() => {
  searchString$
  .pipe(
    debounceTime(350),
    distinctUntilChanged(),
    switchMap(searchString =>
      ajax(`https://api.github.com/search/users?q=${searchString}`)
    ),
    map((networkResponse: any) => networkResponse.response.items)
  )
  .subscribe((suggestions: Array<User>) => setSuggestions(suggestions));
}, [searchString$]);

但是每次用户输入发生变化时,API 调用仍然会进行。

问题:

我认为问题在于每次输入字段的值发生变化时,我也在设置状态:

const handleChange = (
  event: React.ChangeEvent<{}>,
  { newValue }: Autosuggest.ChangeEvent
) => {
  setUserInput(newValue);
};

这导致组件重新渲染并调用 useEffect,最终导致一次又一次地调用 API。

我可能是错的。

如何复制:

我创建了一个复制问题的示例代码沙箱。

提前非常感谢。

4

1 回答 1

3

感谢yurzui在我的推文上的评论,我能够找出问题的原因。

我在每个和解上都创建了一个新Subject的行:

const searchString$: Subject<string> = new Subject<string>();

就在我的组件函数中。

我把它搬走了,它就像一个魅力。

注意:正如yurzui所建议的,不要忘记在 ajax 调用中捕获错误,否则Subject会死掉。

我已经更新了代码沙箱示例,以防万一有人需要参考它。

于 2019-06-26T04:21:03.720 回答