在Redux中修改深层嵌套状态

时间:2016-08-02 11:20:55

标签: reactjs react-redux

我的减速机看起来像这样

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

我的行为看起来像这样

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
    }
}

所以我的州看起来像

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

主要问题是在路线状态上设置数据。我有一种感觉,我的方法是不正确的,并且有一种正确的方法来保存状态中的路线,并且仍然可以修改和保存它。

2 个答案:

答案 0 :(得分:1)

我更喜欢让行动变得简单,并将所有逻辑都转化为减速器。无需将routes对象传递给每个操作。

这是一个简单的例子

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

动作

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

另请参阅Immutable.js,这在这种情况下确实有帮助。

答案 1 :(得分:0)

您应该只在行动中传递路线ID。您可以使用某种不可变性助手来更新reducer中的状态,或者您可以手动更新。例如,使用React update附加组件:

return update(state, {
  base: {
    routes: {
      [action.payload.routeId]: {
        visible: {
          $apply: function (visible) {
            return !visible;
          }
        }
      }
    }
  }
});