Tuesday, 4 April 2017

Higher order reducer applied on mutiple reducers

I m learning deeper redux and I m having some trouble dealing with higher order reducers.

I m trying to understand how it works using a simple example of pagination.

NB : The below code is just a quick example of redux in nodejs context, without transpilation and good practices, and thus, I don't have access to spread / destruc operator, so I m using it statefully, while it's not a good practice at all, and I know that

So, let's imagine that I have a paginable higher order 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;

That I want to apply on these two reducers :

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;

and

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

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

module.exports = arrayReducer;

I create my store as following :

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);

My problem now, is that each time I will dispatch an action like CHANGE_PAGE or CHANGE_DISPLAYED, it always will be handled by the two reducers arr and list, that I don't want.

I had in mind to create new actions like CHANGE_DISPLAYED_LIST and CHANGE_DISPLAYED_ARRAY but it would force me to manage more actions in the paginable reducer that I absolutely dont want to... I m probably missing something important out there.

Any suggestions ?



via Margin

No comments:

Post a Comment