与Redux的React Bootstrap Typeahead AsyncTypehead同步问题

时间:2019-06-05 12:29:31

标签: reactjs redux redux-thunk react-bootstrap-typeahead

我正在使用 react-bootstrap-typehead http://ericgio.github.io/react-bootstrap-typeahead/

在我的react / redux应用程序中开发用户搜索功能

用户搜索会调用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} />
            )}
          />

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

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

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

  dispatch({
    type: REQUEST_RECEIVED,
    data: results
  });
};

我的“ 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);
};

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

REQUEST_SENT
REQUEST_SENT
REQUEST_SENT
REQUEST_RECEIVED
REQUEST_RECEIVED
REQUEST_RECEIVED

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

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

不是很好的解决方案

一件最终起作用的东西(即使我认为这有点像hack)是在AsyncTypehead上添加了一个“延迟”。在AsyncTypeahead组件中添加一个delay={1000}道具可以使api有足够的时间在再次调用该api之前完成其调用。

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

2 个答案:

答案 0 :(得分:0)

我在使用中遇到了其他问题,但是我可以建议一种解决订购问题的方法。

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

理想情况下,您在onSearch()中收到新请求时会取消上一个请求,但这将具有相同的效果。如果用户一直在键入,延迟了足够长的时间以激发onSearch(),但又足够快以致导致请求重叠,那么只有最后一个请求才会显示结果。

答案 1 :(得分:0)

我认为这是 AsyncContainerTypeheadContainer 不同步的组件中的错误。延迟方法在大多数情况下都有效,但即便如此,我也可以以一种不会得到任何结果的方式输入它。对这个答案也不满意,但关闭缓存是保证不会发生这种情况的唯一方法。

useCache={false}