首页 文章

使用axios的redux-thunk的通用dataloader

提问于
浏览
1

我正在开发一个有很多异步操作的应用程序 . 我想和redux-saga一起去,但大多数人都坚持继续使用redux-thunk . 在redux-thunk中,在每个动作中,我们必须使用then,dispatch,catch等来处理异步操作 . 这使得查看动作如此混乱并且将重复大量代码 . 我想为redux-thunk和axios创建一个通用的dataLoader,但是不能考虑这两个帖子(可能是令牌或不是令牌)和get选项 .

这是我的尝试:

export class Company {
/**
* Generic api data loader
*/
static dataLoader(apiUri, onSuccess, onError, data, ...actionArguments) {
  const requestURL = `${API_BASE}${apiuri}`;
  try {
    let options;
    if (data !== undefined) {
      // if we have data to post
      options = {
      method: 'POST',
      url: requestURL,
      body: JSON.stringify(data),
      headers: {
         'Content-Type': 'application/json',
         'X-Requested-With': 'XMLHttpRequest',
      },
      };
    }
  }
  return function(dispatch) {
    axios(options)
    .then(response => {
      dispatch({
        type: onSucess,
        payload: response.data
      });
    })
    .catch(error => {
      dispatch({ type: onError, payload: err});
    });
  }
}

static get(apiUri, onSuccess, onError, ...actionArguments) {
    return this.dataLoader(apiUri, onSuccess, onError, undefined, ...actionArguments);
  }

  /*
   * Shorthand POST function
   */
  static post(apiUri, onSuccess, onError, data, ...actionArguments) {
    return this.dataLoader(apiUri, onSuccess, onError, data, ...actionArguments);
  }

}

我想转换下面的代码来进一步改进这个:

export function showResultofApartment() {
  return (dispatch) => {
    dispatch({ type: 'APARTMENT_FETCH_START' });
    const token = localStorage.getItem('token');
    return axios.get(`${API_URL}/newoffers/apartment/`)
    .then((response) => {
      console.log('response apart', response.data);
        dispatch({ type: 'APARTMENT_FETCH_SUCCESS', payload: response.data });
    })
    .catch((err) => {
      dispatch({ type: 'APARTMENT_FETCH_FAILURE', payload: err });
    });
  };
}

达到这样或更高效:

export function showResultofApartment() {
  return(dispatch) => {
    dispatch({ type: APARTMENT_FETCH_START });
    const token = localStorage.getItem('token');
    return Company.get('/apartments', APARTMENT_FETCH_SUCCESS, APARTMENT_FETCH_ERROR);
    // if post then Company.post('/apartment', APARTMENT_POST_SUCCESS, APARTMENT_POST_ERROR, data)
  }
}

这样它只考虑发布请求(如果数据!== undefined) . 我应该如何有效地处理和发布?

1 回答

  • 1

    好的,你为什么不这样处理它:

    Company.js

    import { merge } from 'lodash';
    import axios from 'axios';
    
    function getHeaders() {
      return {
       'Content-Type': 'application/json'
     };
    }
    
    export class Company {
    
    static callAPI(endpoint, extendedOptions, onSuccess, onError) {
      const initalHttpData = {
        method: 'GET', // By default it's GET in case you didnt specify anything
        headers: getHeaders(),
        url: `${API_BASE}${endpoint}`
      };
    
      // merge takes care of replacing or adding the specific key's provided via the extendedOptions
      const options = merge(initalHttpData, extendedOptions);
    
      // Fire the request for the prepared options.
      let request = axios(options);
    
      // The request once fired, needs it's success handler and error handler.
      return function(dispatch) {
        request
        .then(response => {
          dispatch({
            type: onSucess,
            payload: response.data
          });
        })
        .catch(error => {
          dispatch({ type: onError, payload: err});
        });
      }
    };
    }
    

    然后我们可以使用动作专门将事物传递给这个api工具:

    GET API调用:

    // GET Action
    export function showResultofApartment() {
      return (dispatch) => {
        dispatch({ type: APARTMENT_FETCH_START });
        const token = localStorage.getItem('token');
    
        // FOR GET API
        return Company.callApi('/apartments', {}, APARTMENT_FETCH_SUCCESS, APARTMENT_FETCH_ERROR);
      }
    }
    

    POST API调用:

    // POST Action
    export function showResultOfAppartmentPost() {
      return (dispatch) => {
        dispatch({ type: APARTMENT_FETCH_START });
        const token = localStorage.getItem('token');
    
        // This will merge, essentially replace the method=GET once it gets called.
        const extendedOptions = {
          method: 'POST',
          body: JSON.stringify(data),
          headers: {
             'X-Requested-With': 'XMLHttpRequest',
          }
        }
    
        // FOR GET API
        return Company.callApi('/apartments', extendedOptions, APARTMENT_FETCH_SUCCESS, APARTMENT_FETCH_ERROR);
    }
    

    因此,给出动作,定义它自己的一组API主体或请求 .

相关问题