Peeyush Gupta
Peeyush Gupta

Reputation: 19

How to cancel axios call in react-redux action on change of search text?

I am using redux for doing api call and searching on basis of text. I am dispatching action onChange of text and want to cancel the alternate api calls. Here is my code for Input -

import { useDispatch } from "react-redux";
import { searchData } from "./action";
import "./styles.css";

export default function App() {
  const dispatch = useDispatch()
  const handleChange = (e) => {
    dispatch(searchData({ searchText : e.target.value }))
  }
  return (
    <div className="App">
      <input onChange={handleChange}/>
    </div>
  );
}

Code for action -

export const searchData = ({ searchText = "" }) => {
  return async (dispatch) => {
    dispatch(initiate());
    const response = await axios.post(apiUrl, {
      query: queryToCall(searchText)
    });
    dispatch(success(response));
  };
};

I have tried this solution - how to cancel previous axios with redux in react

Also tried to pass cancelToken as parameter in action but it doesn't seem to work. How can I make this work?

Upvotes: 0

Views: 222

Answers (1)

timotgl
timotgl

Reputation: 2925

If this is for something like an autocomplete input, the simple solution is to only keep the most recent response and ignore the results of all previous requests.

export const searchData = ({ searchText = "" }) => {
  return async (dispatch, getState) => {
    const startedAt = Date.now();
    // Adjust this action to write this timestamp in the state,
    // for example state.mostRecentSearchStartedAt (initialState 0)
    dispatch(initiate(startedAt));
    
    const response = await axios.post(apiUrl, {
      query: queryToCall(searchText)
    });

    // Ignore response if it belongs to an outdated search request
    // - a more recent search has been triggered in the meantime.
    if (getState().mostRecentSearchStartedAt === startedAt) {
      dispatch(success(response));
    }
  };
};

Upvotes: 1

Related Questions