是否可以创建一个访问状态树的多个分支的选择器?

时间:2017-04-01 08:28:57

标签: redux react-redux reselect

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

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

每个reducer更新商店的一个分支

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的分支,但我不知道如何提供两者。这可能吗?

1 个答案:

答案 0 :(得分:2)

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

答案来自redux documentation

  

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

     

然而,常见的问题是“我如何使用combineReducers来处理   这些其他用例?“答案就是:”你没有 -   你可能需要使用别的东西“。一旦你超越了核心   用于combineReducers的用例,是时候使用更多“自定义”减速器了   逻辑,无论是一次性用例的特定逻辑,还是一个   可重用的功能,可以广泛分享。

在文档的同一页面上有how the create reducers that share more of the state的一些建议,但它会比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。