javascript - 高阶 reducer 应用于多个 reducer

标签 javascript node.js redux

我正在学习更深入的 redux,并且在处理高阶 reducer 时遇到一些麻烦。

我试图使用一个简单的分页示例来了解它是如何工作的。

NB:下面的代码只是 Nodejs 上下文中 redux 的一个快速示例,没有转译和良好实践,因此,我无权访问 spread/destruc 运算符,所以我有状态地使用它,虽然这根本不是一个好的做法,而且我知道

所以,让我们假设我有一个可分页的高阶 reducer :

const paginable = (reducer, options) => {
    const PAGE_OFFSET = options.limit;
    const ATTRIBUTE_TO_SLICE = options.attr;
    const initialState = {
        all: reducer(undefined, {}),
        displayed: [],
        limit: PAGE_OFFSET,
        currentPage: 1
    };

    const _actionHandler = {
        'CHANGE_PAGE': (state, newPage) => ({all: state.all, displayed: state.displayed, currentPage: newPage, limit: PAGE_OFFSET}),
        'CHANGE_DISPLAYED': state => ({
            all: state.all, currentPage: state.currentPage, limit: PAGE_OFFSET,
            displayed: state.all[ATTRIBUTE_TO_SLICE].slice((state.currentPage - 1) * PAGE_OFFSET,
                state.currentPage * PAGE_OFFSET)
        })
    };

    return (state = initialState, action) => {
        const handler = _actionHandler[action.type];
        if (handler) {
            return handler(state, action.payload);
        }
        const newAll = reducer(state.all, action);
        state.all = newAll;
        return state;
    };
};

module.exports = paginable;

我想应用于这两个 reducer :

const _actionHandler = {
    'ADD': (state, item) => ({list: [...state.list, item]})
};

const initialState = {
    list: ['a', 'b', 'c', 'd', 'e']
};

const listReducer = (state = initialState, action) => {
    const handler = _actionHandler[action.type];
    return handler ? handler(state, action.payload) : state;
};

module.exports = listReducer;

const initialState = {
    arr: ['z', 'x', 'y', 'b', 'b', 'c', 'd']
};

const arrayReducer = (state = initialState) => {
    return state;
};

module.exports = arrayReducer;

我创建我的商店如下:

const redux = require('redux');
const listReducer = require('./reducer/list');
const arrayReducer = require('./reducer/arrayOfX');
const paginable = require('./reducer/paginable');

const reducers = redux.combineReducers({
    list: paginable(listReducer, {limit: 2, attr: 'list'}),
    arr: paginable(arrayReducer, {limit: 3, attr: 'arr'})
});

const store = redux.createStore(reducers);

我现在的问题是,每次我发送诸如 CHANGE_PAGECHANGE_DISPLAYED 之类的操作时,它总是将由两者处理 reducer arrlist,我不想要。

我打算创建像 CHANGE_DISPLAYED_LISTCHANGE_DISPLAYED_ARRAY 这样的新操作,但这会迫使我在可分页化简器中管理更多我绝对不想管理的操作。 .我可能错过了一些重要的东西。

有什么建议吗?

最佳答案

实际上你不需要 2 个 reducer 。单个高阶 reducer 就可以完成这项工作。

我们可以将类型传递给父包装器并从中返回一个函数。这会在您所在的州创建 2 个条目。

所以,让我们首先创建高阶 reducer :-

const initialState = {
    all: {},
    displayed: [],
    limit: PAGE_OFFSET,
    currentPage: 1
};


export default function wrapper(type) {
  return function(state=initialState,action) {
    //using es6 literals to concatenate the string
    case `CHANGE_DISPLAYED_${type}`:
        // update your state
    case `CHANGE_PAGE_${type}`:
       // update your state
  }
}

现在,按以下方式调用 reducer

   const indexReducer = combineReducers({
     "arrayType": wrapper("array"),
     "listType" : wrapper("list")
   })

有关更多信息,您可以查看重用 reducer 逻辑 here .

如果您遇到任何问题,请告诉我。

关于javascript - 高阶 reducer 应用于多个 reducer ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43223669/

相关文章:

Javascript 加载顺序

javascript - Heroku 配置变量在 Node.js 中无法访问?

javascript - '类型错误 : undefined is not a function' using Protractor

javascript - 防止 MVC 提供 .js、.css 等静态文件

javascript - 页面加载后更改 A 类的 CSS

javascript - Angularjs 获取元素位置

node.js - mailgun 传入邮件事件获取附件 url

javascript - 我试图在单击时从 redux 存储加载数据并更新状态,但状态中的数据在单击时没有更新

javascript - 无法读取未定义的 'map' 的属性

javascript - React redux 路由器显示空白页