如何使用通用API在redux中调度多个动作创建者?

时间:2016-10-10 10:48:58

标签: reactjs redux

我的状态中有2个对象,我通过在请求中传递String myData = spn_staff_list.getSelectedItem().toString(); int position = deliveryStaffResultAdapter.getPosition(myData); // error here (getPosition) 来调用公共API来获取数据。

以下是我id对第一个部分的调用,该部分触发receiveSectionA更新我所在州的sectionA。

fetch

现在我对于触发以下内容的sectionB进行同样的调用: -

export function fetchSection(sectionCode){
  return(dispatch,getState,api)=>{
    const endPoint = 'url/?sectionCode='+sectionCode
    const  method = 'GET'
    const isAuth = true
    const promise = api(endPoint,method,isAuth)
    promise
    .then(response =>
      response.json().then(json => ({
        status:response.status ,
        json
      })
    ))
    .then(
      ({ status, json }) => {
        if( status >= 200 && status < 300) {
          const sectionDictionary = utils.convertSectionsToDictionary(camelizeKeys(json))
          dispatch(receiveSectionA(sectionDictionary))
        }
        if (status >= 400 ) {
          //throw error
        }
      },
      err => {
        console.log("error"+err);
      }
    );
  }
}

既然上面的dispatch(receiveSectionB(sectionDictionary)) 调用是相同的,那么我可以采用任何方式使其成为通用的。我觉得有太多的代码重复。

我在考虑切换案例以基于sectionCode调度不同的操作,但我有大约20个部分,我认为代码会变得非常复杂。

有更好的处理方法吗?

4 个答案:

答案 0 :(得分:1)

据我了解,您正在寻找dynamic function call。您可以使用eval,这可能会导致意外结果。所以,请谨慎使用。

期待您有receiveSectionAreceiveSectionB这两个功能;

export function fetchSection(sectionCode){
  return(dispatch,getState,api)=>{
     ....................
    ))
    .then(
      ({ status, json }) => {
        if( status >= 200 && status < 300) {

          const sectionDictionary = utils.convertSectionsToDictionary(camelizeKeys(json))
          let funToCall = 'receiveSection' + sectionCode + '(sectionDictionary )'; // preparing function to call
          dispatch(eval(funToCall)); // Calling Function
        }
        if (status >= 400 ) {
          //throw error
        }
      },
      err => {
        console.log("error"+err);
      }
    );
  }
}

编辑: 详细了解eval,尤其是Security部分 - https://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/

答案 1 :(得分:0)

稍微思考一下,显然eval不是一个好的选择。

我想我会尝试Javascript支持的一项令人惊奇的事情,它将函数作为参数传递。

在调度动作时,我将receiveActionCreator作为回调传递。

所以我的fetch现在是: -

export function fetchSection(callback,sectionCode){
  return(dispatch,getState,api)=>{
     ....................
    ))
    .then(
      ({ status, json }) => {
        if( status >= 200 && status < 300) {

          const sectionDictionary = utils.convertSectionsToDictionary(camelizeKeys(json))

          dispatch(callback(sectionDictionary)); // Calling Function
        }
        if (status >= 400 ) {
          //throw error
        }
      },
      err => {
        console.log("error"+err);
      }
    );
  }
}

现在,当我通过避免代码重复从不同的部分调度动作时,我可以从不同的点传递多个接收器。

答案 2 :(得分:0)

我无法从reducer中看到你的代码,但在我看来,你对行动有太多的逻辑。通常,操作仅用于修改应用程序状态,因此请考虑应用程序状态的形状,并在减速器可以计算状态的操作中提供最少的信息。此外,如果你必须转换json并检查每个请求的状态代码,为什么不在api模块中执行它,如果你不能对错误做任何事情,那么你不应该处理它们,在api中处理或在app状态中反映它们。应用程序业务逻辑总是存在于reducer中。在此之后,您的操作看起来会更好,您不必担心代码重复。希望这会对你有所帮助。

答案 3 :(得分:0)

所以在搜索完之后我终于找到了我在redux-docs中读到的东西。

我使用重用reducer逻辑来处理重复的动作,状态。这基本上围绕我的reducer函数包装一个父函数,我将id作为参数传递给我,然后动态地从我的id创建动作类型。

以下代码应该清楚地解释清楚。它来自文档本身。

function createCounterWithNamedType(counterName = '') {
    return function counter(state = 0, action) {
        switch (action.type) {
            case `INCREMENT_${counterName}`:
                return state + 1;
            case `DECREMENT_${counterName}`:
                return state - 1;
            default:
                return state;
        }
    }
}