重用Redux-react异步请求动作创建器/减速器

时间:2016-05-25 09:41:27

标签: reactjs redux react-redux redux-thunk

所以我有这个简单的异步请求操作创建者,使用axios表示请求,redux-thunk发送操作。我想为不同的请求重复使用相同的动作创建器 - 因此每个请求都有自己的状态。我将尝试展示一些代码,然后解释更多。这是我的动作创作者

function responseOK(response){
  return {
    type: RESPONSE_OK,
    payload: response,
  }
}

function loadingChangedStatus(isLoading) {
  return {
    type: IS_LOADING,
    isLoading:  isLoading,
  }
}

function handleError(errorID){
  return {
    type: HANDLE_ERROR,
    errorID: errorID,
  }
}



export function makeRequest( URL){

  return function(dispatch, getSate){

      dispatch( loadingChangedStatus(true) );

      axios.get( URL )
        .then(function(response){
          dispatch(loadingChangedStatus(false));
          dispatch(responseOK(response));

        })
        .catch(function (response) {
          dispatch(loadingChangedStatus(false));
          dispatch(handleError('connection_error'));
        });
  }

}

我的减速机 reducerRequest

export default function(state = {isLoading:false, payload:false,errorID:false}, action){

  switch (action.type) {

    case IS_LOADING:
      return Object.assign({}, state, {
        isLoading: action.isLoading,
      });
      break;

    case RESPONSE_OK:
        return Object.assign({}, state, {
          isLoading: state.isLoading,
          payload: action.payload,
        });
        break;

    case HANDLE_ERROR:
        return Object.assign({}, state, {
          isLoading: state.isLoading,
          payload: action.payload,
          errorID:action.errorID,
        });
        break;

    default:
      return state;
  }

}

在这里开始我的问题

我像这样组合减速器:

import { combineReducers } from 'redux';
import Request from "./reducerRequest";

const rootReducer = combineReducers({
  // I WANT EACH OF THESE TO BE SEPARATE INSTANCE BUT USE THE SAME ACTION CREATOR / REDUCER
  defaults: Request,
  updates: Request,
});

export default rootReducer;

在我的组件中:

function mapStateToProps( {defaults, updates} ){
  return {defaults, updates} 
}

function mapDispatchToProps( dispatch ){
  return bindActionCreators({ makeRequest}, dispatch);
} 

问题:我想为不同的请求重复使用我的动作创建器。我怎么能

  1. 致电makeRequest('www.defaults.com'),最终以defaults
  2. 结束
  3. 致电makeRequest('www.updates.com'),最终以updates
  4. 结束

    现在,我可以通过图像来解决这个问题的唯一方法是为每个请求编写自己的动作创建者和自己的缩减器 - 只需要大量的复制粘贴 - 感觉不对。

    如何重复使用我的操作创建器和缩减器在组件中创建defaultsupdates的2个独立实例?

1 个答案:

答案 0 :(得分:1)

您可以为每个操作添加减速器操作的前缀:

export default function(namespace) 
   return function(state = {isLoading:false, payload:false,errorID:false}, action){

  switch (action.type) {

    case namespace + IS_LOADING:
      return Object.assign({}, state, {
        isLoading: action.isLoading,
      });
      break;

    case namespace + RESPONSE_OK:
        return Object.assign({}, state, {
          isLoading: state.isLoading,
          payload: action.payload,
        });
        break;

    case namespace + HANDLE_ERROR:
        return Object.assign({}, state, {
          isLoading: state.isLoading,
          payload: action.payload,
          errorID:action.errorID,
        });
        break;

    default:
      return state;
  }
}
}

然后添加命名空间

function responseOK(namespace, response){
  return {
    type: namespace + RESPONSE_OK,
    payload: response,
  }
}


const rootReducer = combineReducers({
  // I WANT EACH OF THESE TO BE SEPARATE INSTANCE BUT USE THE SAME ACTION CREATOR / REDUCER
  defaults: Request("DEFAULTS_"),
  updates: Request("UPDATES_"),
});

然后在调用make requests

时使用命名空间
call makeRequest('DEFAULTS_', 'www.defaults.com') and it ends up in defaults
call makeRequest('UPDATES_', 'www.updates.com') and it ends up in updates

HTH