wnoveno wnoveno - 4 months ago 31
React JSX Question

Modifying a deep nested state in Redux

My reducer looks like this

const INITIAL_STATE = { map:[], routes:[], road:null};


export default function (state = INITIAL_STATE, action){
switch(action.type){
case TOGGLE_ROUTE_VISIBILITY : return { ...state, routes: action.payload };
break;
case SAVE_ROAD_ROUTE : return {...state, routes: action.payload };
break;
default:
return state;
}
}


and my action looks like this

export function toggleVisibility(id, routes){
const i = _.findIndex(routes, o => { return o.id = id });
routes[i].visible = !routes[i].visible;
return {
type: TOGGLE_ROUTE_VISIBILITY,
payload: routes
}
}


So my state looks like

state:{
base:
routes : [
{id:1, visible:true},
{id:2, visible:true},
]
}}


The main problem is setting the data on the routes state. I have a feeling that my approach is incorrect and there's a proper way of saving the routes in the state and still be able to modify and save it.

Answer

I prefer to keep actions simple and move all logic into reducers. There is no need to pass routes object into each action.

Here is simple example

const INITIAL_STATE = {map: [], routes: [], road: null};

export default function (state = INITIAL_STATE, action) {
    switch (action.type) {
        case TOGGLE_ROUTE_VISIBILITY :
            return Object.assign(state, {
                routes: state.routes.map(function (route) {
                    if (route.id === action.id) {
                        route.visible = !route.visible;
                    }
                    return route;
                })
            });
            break;
        case SAVE_ROAD_ROUTE:
            return Object.assign(state, {
                routes: [
                    ...state.routes,
                    {
                        id: action.id, // or just add some ID generator here
                        visible: true
                    }
                ]
            });
            break;
        default:
            return state;
    }
}

Action

export function toggleVisibility(id){
    return {
        type: TOGGLE_ROUTE_VISIBILITY,
        id: id
    }
}

Also have a look at Immutable.js which really helps in this scenario.