2

我正在开发一个 Redux 项目,其中包含一堆组合的减速器

const rootReducer = combineReducers({
    reducer1,
    reducer2,
    ...
});

每个 reducer 更新 store 的一个分支

sampleStore = {
    reducer1: {a1: 7, b1: 5, c1: 6, ...},
    reducer2: {a2: 3, b2: 2, c2: 9, ...},
    reducer3: {a3: 1, b3: 4, c3: 2, ...},
    ...
}

现在我正在尝试添加需要访问商店的两个分支而不重构整个项目的逻辑。例如,我想要一个能够执行以下操作的减速器:set c3 = f(a1, a2).

目前我正在尝试使用重新选择,但我迷路了。在 reducer1/selector.js 我有

export const derivedVariableSelector = createSelector(
    a1Selector,
    a2Selector,
    (a1, a2) => a1 + a2
); 

我正在尝试创建一个减速器

function setC3(state) {
    return Object.assign({}, state, {
        c3: state.c3 + derivedVariableSelector(state)
    });
}

但是,当调用 setC3 时,derivedVariableSelector 将永远不会收到足够的存储来完成其工作。它要么接收包含 a1 的分支,要么接收包含 a2 的分支,但我不知道如何同时提供这两者。这可能吗?

4

1 回答 1

3

简短的回答是“不”,只要您使用combineReducers组合所有减速器。

更长的答案来自redux 文档

Redux 附带的 combineReducers 实用程序非常有用,但特意将其限制为处理单个常见用例:通过将更新每个状态切片的工作委托给特定切片缩减器来更新作为普通 Javascript 对象的状态树。它不处理其他用例,例如由 Immutable.js Maps 组成的状态树,尝试将状态树的其他部分作为附加参数传递给 slice reducer,或执行 slice reducer 调用的“排序”。它也不关心给定的 slice reducer 是如何工作的。

那么,常见的问题是“我如何使用 combineReducers 来处理这些其他用例?”。答案很简单:“你不需要——你可能需要使用别的东西”。一旦你超越了 combineReducers 的核心用例,就该使用更多“自定义”reducer 逻辑了,无论是一次性用例的特定逻辑,还是可以广泛共享的可重用函数。

在文档的同一页面上,有一些关于如何创建共享更多状态的 reducer 的建议,但它会比comibineReducers现在更加手动。

我自己以前没有尝试过这样的事情,但是按照文档中的示例,这样的事情可能对你有用:

import { combineReducers } from 'redux'
import reduceReducers from 'reduce-reducers'

const reducer1 = (state = {}, action) => {
    switch (action.type) {
        // handle actions
        default: 
            return state
    }
}

const reducer2 = (state = {}, action) => {
    switch (action.type) {
        // handle actions
        default: 
            return state
    }
}

const reducer3 = (state) => {
    return {
        ...state,
        // use the root state for the reducerC value
        reducerC: makeValue(state.reducer1, state.reducer2)
    }
}

const rootReducer = reduceReducers(combineReducers({reducer1, reducer2}), reducer3)

这使用库reduce-reducers以不同的方式组合 reducer。

于 2017-04-01T12:06:45.987 回答