React Bootstrap Typeahead AsyncTypehead 与 Redux 同步问题

K. *_*ers 5 reactjs redux redux-thunk react-bootstrap-typeahead

我正在使用react-bootstrap-typehead在我的react/redux应用程序中开发用户搜索功能: http://ericgio.github.io/react-bootstrap-typeahead/

用户搜索调用 API 来搜索用户列表,因此我使用AsyncTypeahead组件。

由于我使用的是 Redux,因此我将加载和搜索结果存储在商店中,因此我的代码如下所示:

const { searchPeople, loading, searchResults, selectedPerson } = this.props;
          <AsyncTypeahead
            isLoading={loading}
            options={searchResults}
            labelKey="DisplayName"
            clearButton
            minLength={5}
            onSearch={searchPeople}
            onChange={handleChange}
            placeholder="Search for a user..."
            renderMenuItemChildren={option => (
              <TypeaheadItem key={option.EmployeeID} item={option} {...this.props} />
            )}
          />
Run Code Online (Sandbox Code Playgroud)

在 Redux 中调用onSearch={searchPeople}一个操作来调用 API 并将结果存储在“searchResults”中:

const searchPeople = term => async dispatch => {
  dispatch({
    type: REQUEST_SENT
  });

  const results = await dispatch(applicationActions.peopleSearch(term));

  dispatch({
    type: REQUEST_RECEIVED,
    data: results
  });
};
Run Code Online (Sandbox Code Playgroud)

我的“peopleSearch”功能存储在另一个操作中,我在其中拥有所有用户搜索功能。这就是为什么我要派去另一项行动。

const peopleSearch = searchTerm => async () => {
  const url = `https://api-personSearch.test.com/search=${searchTerm}&Output=JSONP`;
  const response = await fetchJsonp(url);
  const data = await response.json();
  return data.slice(0, 10);
};
Run Code Online (Sandbox Code Playgroud)

如果我搜索输入缓慢的用户,一切都会完美。问题是,如果我快速或以正常速度输入用户名,则会在调用任何“REQUEST_RECEIVED”之前调用多个“REQUEST_SENT”调度。因此,查看 Redux Dev Tools 显示的结果如下所示:

REQUEST_SENT
REQUEST_SENT
REQUEST_SENT
REQUEST_RECEIVED
REQUEST_RECEIVED
REQUEST_RECEIVED
Run Code Online (Sandbox Code Playgroud)

最终发送到界面的内容并不是用户最终输入的最后一个字母的结果。

将 AsyncTypeahead 与 Redux 结合使用以便结果按照发送的正确顺序返回的正确方法是什么?

不是很好的解决方案

最终起作用的一件事(尽管我认为这是一种黑客行为)是向 AsyncTypehead 添加“延迟”。向 AsyncTypeahead 组件添加delay={1000}prop 可以为 api 提供足够的时间来完成对 api 的另一次调用之前的调用。

如果可能的话,我想找到更好的解决方案。

Dav*_*ess 1

我在使用中遇到了不同的问题,但我可以建议解决排序问题的方法。

  1. 将最后一个查询字符串存储在 Redux 中。
  2. 当请求完成时,如果不是最后一个查询字符串,则忽略它。

理想情况下,您会在收到新请求时取消上一个请求onSearch(),但这会产生相同的效果。如果用户继续键入,延迟足够长的时间以onSearch()被触发,但又足够快以导致重叠请求,则只有最后一个请求才会显示结果。