I am developing a user search feature in my react/redux application using react-bootstrap-typehead: http://ericgio.github.io/react-bootstrap-typeahead/
The user search calls an API to search the list of users, so I am using the AsyncTypeahead component.
Since I are using Redux, I am storing the loading and search results within the store, so my code looks something like this:
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} />
)}
/>
The onSearch={searchPeople} calls an action in Redux to call the API and store the results in "searchResults":
const searchPeople = term => async dispatch => {
dispatch({
type: REQUEST_SENT
});
const results = await dispatch(applicationActions.peopleSearch(term));
dispatch({
type: REQUEST_RECEIVED,
data: results
});
};
My "peopleSearch" function is stored in another action where I have all of our user search functionality. That is why I am dispatching to another action.
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);
};
Everything works perfectly if I search for a user typing slowly. The problem is, if I type a users name quickly or at a normal pace, multiple "REQUEST_SENT" dispatches get called before any "REQUEST_RECEIVED" get called. So looking at the Redux Dev Tools shows results looking like this:
REQUEST_SENT
REQUEST_SENT
REQUEST_SENT
REQUEST_RECEIVED
REQUEST_RECEIVED
REQUEST_RECEIVED
What ends up getting sent to the interface does not end up being the results for the last letter the user ended up typing.
What would be the proper way to use AsyncTypeahead with Redux so that the results are returned in the proper order that they are sent?
Not Great Solution
One thing that ended up working (even though I think it's sort of a hack) is adding a "delay" to the AsyncTypehead. Adding a delay={1000} prop to the AsyncTypeahead component gives the api just enough time to finish it's call before another call to the api is made.
I would like to find a better solution if one is possible.