【问题标题】:How to use common API for dispatching multiple action creators in redux?如何使用通用 API 在 redux 中调度多个动作创建者?
【发布时间】:2016-10-25 16:03:01
【问题描述】:

我的状态中有 2 个对象,我通过在请求中传递 id 来调用一个通用 API 来获取数据。

以下是我的 fetch 调用第一个 Section,它触发 receiveSectionA 以更新我所在州的 sectionA。

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);
      }
    );
  }
}

现在我对 sectionB 发出相同的调用,触发如下:-

dispatch(receiveSectionB(sectionDictionary))

现在既然上面的fetch 调用是一样的,有什么办法可以使这个通用的。感觉代码重复太多了。

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

有没有更好的处理方法?

【问题讨论】:

    标签: reactjs redux


    【解决方案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/

    【讨论】:

    • 这看起来很有趣。但是,您所说的意外结果是什么意思?
    • 答案更新了链接。阅读,学习,忘记...:D
    【解决方案2】:

    想了想,显然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);
          }
        );
      }
    }
    

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

        所以在搜索了这个之后,我终于找到了我在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;
                }
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2020-05-23
          • 1970-01-01
          • 2018-09-08
          • 2020-02-19
          • 1970-01-01
          • 2021-04-29
          • 2020-10-31
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多