score:0

i suggest breaking your reducer up into smaller functions.

below are four functions, each in turn deals with a smaller part of the state. (though in each case the first parameter is called state, it's different every time). the action though, is always the same.

i haven't checked this code for correctness, but i hope you get the idea.

function reducertop(state, action) {
    switch (action.type) {
        case set_val:
            return object.assign({}, state, {
                [action.toplevel]: reducernext(state[action.toplevel], action);
            });
    }
    return state;
}

function reducernext(state, action) {
    switch (action.type) {
        case set_val:
            return object.assign({}, state, {
                [action.nextlevel]: reducerarray(state[action.nextlevel], action);
            });
    }
    return state;
}

function reducerarray(state, action) {
    switch (action.type) {
        case set_val:
            const index = state.findindex((item) => item.id === action.id);
            if (index > -1) {
                return [
                    ...state.slice(0, index),
                    reducerfinal(state[index], action),
                    ...state.slice(index + 1)
                ];
            }
    }
    return state;
}

function reducerfinal(state, action) {
    switch (action.type) {
        case set_val:
            return object.assign({}, state, {
                value: action.value
            });
    }
    return state;
}

score:0

i think it is a problem of redux itself -- it is just too low-level, and some things (like nested updates, for instance), just should be easier. also, i believe that there is no problems to put all business logic into action creators, and inside reducers just update our state (and to perform nested updates, if needed).

another unnecessary thing, from my point of view -- constants. we usually have some object with all redux entities (for instance, reducers), and i think it should be enough to figure out all needed constants.

with this thoughts, i wrote a library redux-tiles, which does exactly that -- based on given type, it creates constants, handles async functions, and creates reducers for you. so, typical api request will look like the following:

import { createtile } from 'redux-tiles';
const requesttile = createtile({
  type: ['api', 'request'],
  fn: ({ api, params }) => api.get('/items', params),
});

it will create all constants, a reducer, and also handle failure, success and loading states. you can take a look at the full hn api example with redux-tiles here. you might find there nesting, which will update everything automatically, you just need to return an array of values to nest.


Related Query

More Query from same tag