【问题标题】:Redux and within a reducer accessing a different reducer, how?Redux 和在 reducer 中访问不同的 reducer,如何?
【发布时间】:2016-06-21 11:32:57
【问题描述】:

所以,我有一个有多个 reducer 的应用,因此关联了多个 action creators。

有时我的一个 reducer 会更新状态(由于编辑),因此,我必须确保其他 reducer 看到此更新并相应地调整其状态。

把它想象成一个用户选择了“sneakers”,这个状态管理在一个叫做 productsReducer 的 reducer 中。因此,当用户通过应用程序流程时,他们会获得与之关联的couponsReducer ......但用户可以随时“编辑”,所以如果他们随后编辑“运动鞋”并说,选择另一个制作人,我必须能够实时更改 couponsReducer,因为进度模式需要反映这一点。我可以通过流到优惠券页面来做到这一点,因为在该页面上我只是协调 componentWillMount 上的数据......但问题是我有一个进度模式,在进入优惠券页面之前,用户可以打开进度模式...这里会出现不匹配...

我知道啰嗦,我只是想解释一下我的情况。

所以,我希望能够从 productsReducer 中调用“其他减速器”或它们的动作创建者。

中间件在这里是否合适,我在其中嗅探某个“action.type”,如果我看到它,我可以调度其他 action.type,或者有没有办法从 productsReducer 中调用动作创建者?

importing: import * as coupons from './couponsActions' 以及我需要的任何其他操作似乎都不合适。

【问题讨论】:

    标签: redux react-redux


    【解决方案1】:

    根据应用程序状态更新状态是一种反模式。解决方案更简单:

    如果一个操作影响多个减速器,请在关心的减速器中订阅该操作。

    所以当用户选择sneakers 时,触发这些操作

    { type: 'item_select', payload: 'sneakers' }
    

    然后在couponsReducer,有这样的东西:

    function (state = initialState, action) {
      if (action.type == 'item_select') {
        return { ...state, activeProduct: action.payload);}
      }
      return state;
    }
    

    您不希望级联更新,其中状态依赖于其他状态的变化。您需要一个简单的调度架构,其中一个操作会同时影响所有内容。

    【讨论】:

    • 太棒了。我主要关心的是保持在适当的范式内而不是反模式。我能够有效地做我需要的事情,就像你建议的那样,按照我的需要订阅。太好了,谢谢。
    • "根据应用程序状态更新状态是一种反模式" ?这没有任何意义。 reducer 函数的全部意义在于您根据 当前状态 和操作做出决策。
    • @markerikson 不,reducer 旨在处理操作,而不是状态更改。状态的变化应该始终是动作的结果。由于动作被调度而创建动作是一种反模式。
    • 似乎我们的术语不匹配。我认为您想说的是“基于状态中的 diffs 做事是个坏主意”?而且我仍然不同意您关于操作的声明,尤其是在您使用中间件的情况下。调度一个动作,让中间件拦截它,然后调度一个或多个其他动作作为响应是完全有效的。这就是中间件的用途。
    • 是的,我认为在这种情况下我们说的是同一件事。你说得对,我说错了动作——动作可以引发其他动作就好了,反模式是冗余动作或由reducer触发的动作或因为事后对商店的更改。
    【解决方案2】:

    在许多情况下,在多个 reducer 中处理相同的操作就足够了(这是 redux 中官方推荐的做事方式)。因此,请始终先尝试该解决方案。

    在更复杂的情况下,您可以使用一些库。例如使用redux-saga 你可以这样处理:

    function* watchItemSelect() {
        while(true) {
            // Wait for the action you are interested in
            const action = yield take('ITEM_SELECT');
            // Send another action
            yield put({type: 'OTHER_ACTION'}) 
            // The loop will now continue and wait until the next ITEM_SELECT action comes
        }
    }
    

    还有其他库做同样的事情,但略有不同。他们中的大多数都受到榆树语言的启发:

    这个 repo 也有一些关于上述库中的想法的信息:

    redux-architecture

    【讨论】:

    • 在您的应用中再添加一个库来解决您的问题不是解决方案。这是 Redux 初始库的糟糕设计。
    猜你喜欢
    • 2017-12-31
    • 2023-03-22
    • 2020-05-30
    • 1970-01-01
    • 2021-09-15
    • 2016-05-30
    • 1970-01-01
    • 2017-03-28
    • 2017-04-02
    相关资源
    最近更新 更多