【问题标题】:Adding a callback to a Redux Reducer向 Redux Reducer 添加回调
【发布时间】:2017-11-03 15:43:25
【问题描述】:

向传递给动作的action.data 添加回调是否有任何错误/反模式(就“thinking-in-react/redux”而言)?

// reducer
ACTION_FOR_REDUCER() {
  var x = 123
  if ( action.data.callback ) action.data.callback( x )
  return {
    something: action.data.somedata
  }
},

然后在调用该操作时(可能在容器中)稍后在 App 中访问该数据

// later in the app
this.props.dispatch(changeSomething({
  somedata: somedata,
  callback: (x) => { console.log(x) }
}))    

【问题讨论】:

    标签: reactjs callback redux


    【解决方案1】:

    思路没有错,实现才是。

    不要添加回调,而是从操作返回一个承诺(您将需要redux-thunk 中间件或一些类似的替代品)。

    那么你可以简单地做:

    dispatch(myAction).then(callback);
    

    当然,您也可以在回调中简单地调度另一个动作,这通常最终成为一个复合动作。

    const myAction = ...
    const callbackAction = ...
    
    const compoundAction = () => dispatch => {
         dispatch(myAction())
             .then(() => dispatch(callbackAction()));
    };
    

    【讨论】:

      【解决方案2】:

      Redux 的第三个原则(在introduction section of the docs 中列出)是'使用纯函数进行更改'

      纯函数是在给定相同输入的情况下始终返回相同结果且不会产生任何副作用的函数。有一个回调日志肯定会是一个副作用!

      The docs go on to say:

      reducer 保持纯净非常重要。在 reducer 中你不应该做的事情:

      • 改变它的论点;
      • 执行 API 调用和路由转换等副作用;
      • 调用非纯函数,例如Date.now() 或 Math.random()。

      这背后的原因是它使您的减速器可预测 - 您知道,给定具有特定负载的操作,您可以保证具有相同的输出。这使您的应用程序更易于作为开发人员理解,并且更易于单元测试。

      如果您想在某个动作发生时执行副作用,您应该安装一个允许您执行此操作的中间件 - 一些常见示例如下:

      • redux-thunk,它允许您分派可以依次分派操作的函数(通常用于进行 API 调用)
      • redux-logger,允许您注销已调度的操作。
      • redux-devtools-extension,可让您在 Chrome devtools 扩展程序中查看您的状态和操作。

      如果您找不到满足您需要的中间件包(说实话,很少见 - 已经有很多了!),您可以很容易地write your own

      【讨论】:

      • 如果你想调用一些外部API,我建议你自己创建middleware
      • @Ematipico:将在答案中添加一些关于中间件的细节:)
      • 谢谢,我认为 redux-thunk 是我正在寻找的。但是,关于突变的主题,突变不是后来作为dispatch 的一部分发生的,而不是在reducer 本身中发生的吗?
      【解决方案3】:

      回调会引入副作用,因此在使用 Redux 时,您应该考虑使用结果返回一个新状态,例如使用 done: true 标志并在 componentDidUpdate 中对其做出反应。

      要管理异步和效果,您可以使用redux-sagaredux-thunkRxJs 或其他库。 如果你想坚持使用回调,为什么还要使用 Redux?

      【讨论】:

        猜你喜欢
        • 2016-06-23
        • 1970-01-01
        • 2020-12-05
        • 1970-01-01
        • 2021-03-03
        • 2017-04-16
        • 2018-03-31
        • 2017-07-12
        • 1970-01-01
        相关资源
        最近更新 更多