redux 基于减速器B更新减速器A

aij0ehis  于 2023-06-30  发布在  其他
关注(0)|答案(1)|浏览(123)

目标:

根据一些滤镜更新我最喜欢的颜色。

设置:

有两个减速器:filterscolors

export function filters(state = {
  noRed: false,
  noBlack: false,
}, action) { ... })

export function colors(state = {
  red: true,
  black: true,
  blue: true
}, action) { ... })

我想基于filters更新colors。我可以同时分派setFiltersetColor,但这不起作用,因为setColor应该只在filters完全减少之后才发生。我也可以考虑将filterscolors组合在一起,但我希望将它们分开。
实现我的目标的最好方法是什么?我真正需要的是以下内容:

export function colors(state = [], action) {
  switch (action.type) {
    case constants.SET_FILTER:
      // assume I can access filters reducer here
      var filters = filtersReducer
      var colors = applyFilters(state.colors, filters)
      return colors
    case constants.SET_COLOR:
      return action.colors
    default:
      return state
  }
}

或者我可以在filters reducer内部调度一个操作,但这是一个反模式。

f5emj3cl

f5emj3cl1#

在slice reducers之间共享数据官方文档解释得很清楚。
SET_COLOR_BY_FILTER操作将首先设置滤镜状态,然后使用下一个滤镜状态来设置颜色。

import { combineReducers, createStore } from 'redux';

function filters(state = { noRed: false, noBlack: false }, action) {
    switch (action.type) {
        case 'SET_FILTER':
            return { ...state, ...action.payload };
        default:
            return state;
    }
}

function colors(state = { red: true, black: true, blue: true }, action) {
    switch (action.type) {
        case 'SET_COLOR':
            return { ...state, ...action.payload };
        default:
            return state;
    }
}

const colorsByFilters = (state, action) => {
    switch (action.type) {
        case 'SET_COLOR_BY_FILTER': {
            const filersState = filters(state.filters, { type: 'SET_FILTER', payload: action.payload });
            return {
                filters: filersState,
                colors: colors(state.colors, {
                    type: 'SET_COLOR',
                    payload: { black: !filersState.noBlack, red: !filersState.noRed },
                }),
            };
        }
        default:
            return state;
    }
};

const combinedReducers = combineReducers({ filters, colors });

const root = (state, action) => {
    const intermediateState = combinedReducers(state, action);
    const finalState = colorsByFilters(intermediateState, action);
    return finalState;
};

const store = createStore(root);

store.subscribe(() => {
    console.log('state: ', store.getState());
});

store.dispatch({ type: 'SET_COLOR_BY_FILTER', payload: { noBlack: true, noRed: true } });

输出:

state:  {
  filters: { noRed: true, noBlack: true },
  colors: { red: false, black: false, blue: true }
}

相关问题