取消之前的请求实时搜索reactjs

时间:2018-01-05 23:08:31

标签: react-redux axios debounce

我需要使用实时搜索axios请求取消之前的请求 - 我正在使用限制 - 去抖来发出请求,但是当现有字被删除并且新值被更新时我遇到了问题 - 结果显示为之前的单词在某些情况下,我认为我需要取消以前对同一个requestID的所有请求,阅读文章,但它们都不适用于我的用例。任何帮助,这是我的代码赞赏。

减速器:

switch (action.type) {
case GETTING_DATA:
  return {
    ...state,
    results: action.payload,
  };
case SEARCH_DATA:
  return {
    ...state,
    Results: action.payload,
  };



export function getSearch(value) {
  return (dispatch) => {
    dispatch({
      type: GETTING_DATA,
    });
    const arg = {
      search: value,
    };
    apiGet('abc', arg).then(response => 
     getResults(dispatch, response));
  };
}
const getResults = (dispatch, response) => {
  dispatch({
    type: SEARCH_DATA,
    payload: response.data,
  });
};

服务:

export const apiGet = async (path = '', args = {}) => {
  const endpoint = "/aaa/aaa/aaa";
  try {
    return axios.get(endpoint, getConfig());
  } catch (e) {
  }
};

2 个答案:

答案 0 :(得分:5)

尝试以下方法:

value作为有效负载传递给GETTING_DATA操作。这将在状态中存储最新请求的值。

然后,在getResults中将相同的值与响应数据一起发送到reducer。在reducer中,检查从getResults传递的值是否与通过GETTING_DATA存储在状态中的值相同。

如果是这样,此数据将响应最新请求,因此您希望将其存储在该状态中。否则,你可以忽略它。

换句话说:

<强>动作:

switch (action.type) {
case GETTING_DATA:
  return {
    ...state,
    lastRequestTime: action.payload,
  };
case SEARCH_DATA:
  if (action.payload.lastRequestTime === state.lastRequestTime) {
    return {
      ...state,
      Results: action.payload.response,
    };
  } else {
    return state
  }

<强>动作:

export function getSearch(value) {
  return (dispatch) => {
    const lastRequestTime = Date.now()
    dispatch({
      type: GETTING_DATA, 
      payload: lastRequestTime
    });
    const arg = {
      search: value,
    };
    apiGet('abc', arg).then(response => 
     getResults(dispatch, { response, lastRequestTime }));
  };
}
const getResults = (dispatch, response) => {
  dispatch({
    type: SEARCH_DATA,
    payload: response.data,
  });
};

答案 1 :(得分:0)

您可以创建一个小的辅助包装器,并在需要取消上一个请求的任何地方使用它:

// ../services.js

function createApi(baseURL) {
  const axiosInst = axios.create({
    baseURL,
  });
  // here you can set default headers:
  axiosInst.defaults.headers.common['Content-Type'] = 'application/json';
  // return the function with closure variable to use for canceling
  return (type = 'get') => {
    let call = null;
    return (url, data, config) => {
      if (call) {
        call.cancel('Only one request allowed!');
      }
      call = axios.CancelToken.source();
      const extConf = {
        cancelToken: call.token,
        ...config,
      };
      switch (type) {
        case 'request':
          return api[type](extConf);

        case 'get':
        case 'delete':
        case 'head':
          return api[type](url, extConf);

        default:
          return api[type](url, data, extConf);
      }
    };
  };
}

export const baseApi = createApi('http://localhost:5000/api/')

然后在这样的任何地方使用它:

import baseApi from '../servises.js';

const fetchItemsService = baseApi('post');

//...
componentDidMount() {
  fetchItemsService('/items').then(() => {});
}
//...