如何用对象的双重嵌套数组不变地更新/替换React Redux State?

时间:2019-06-11 02:24:15

标签: javascript reactjs react-native redux react-redux

我的redux状态有一个SessionList,它是一个SessionObjects数组,每个SessionObject都有一个HandObjects数组。

我通过添加新的HandObject使用状态来更新单个SessionObject,但是我想用更新后的SessionObject更新Redux存储(如果可能的话,是不变的)。

SessionList在SessionList中的索引是action.payload.Id(我想?我将显示我的SessionObject构造函数)

**添加会话工作正常,我仅使用商店中已有的会话更新会话

我尝试了所有可以找到的链接,但是我的代码是如此不同,以致于我似乎无法正确更新SessionList。

我的减速器,具有初始状态 store.js(我的减速器所在的位置)

const initialState = {
    SessionList: [],
}
...
case "UPDATE_SESSION":
            //action.payload is a SessionObject
            //action.payload.Id is the Id that i want to update
            // i want to set SessionList[action.payload.Id] = action.payload
            state = {
                ...state,
                SessionList : state.SessionList.map((item, index) => {
                    if (index != action.payload.id) {
                      return item
                    }

                    return action.payload
                    //This code doesn't visibly do anything that I can find
                  })

                // *******FIRST TRY*******
                // ...state,
                //  SessionList: {
                //     ...state.SessionList,
                //     SessionList[action.payload.id] : action.payload 
//syntax error, but basically what i want to do
                //      }
                // }
                // ***********************
            };
            break;

SessionObject构造函数 Session.js

export function SessionObject(_id, _name, _hands) {
    this.id = _id, //int
    this.name = _name, //string
    this.HandList = _hands //array of HandObject objects
}
var defaultSession = new SessionObject(0, "default", []);

*如果我做错了, 我打电话 (Session.js)

this.props.navigation.state.params.updateMethod(this.state.Session); //update store

来自堆栈导航器子组件。
然后在父组件中, 我打电话 (Home.js)

UpdateSession = (session) => {
      this.props.updateSession(session);
    };

我的调度员看起来像: (Home.js)

updateSession: (session) => {
        dispatch({
          type: "UPDATE_SESSION",
          payload: session
        });
      }

从测试中,我可以肯定我的减速器被正确调用了。

我想用SessionList正确索引中的action.payload替换SessionObject。

编辑 *

Session.js

addItem = () => {
        this.setState((state, props) => ({
        Session : {
          ...state,
          HandList: [...state.Session.HandList, new HandObject(state.HandCount)]
        },
        HandCount : state.HandCount + 1,
        }));
        this.props.navigation.state.params.updateMethod(this.state.Session); //update store
    };

Session.js中的状态是一个SessionObject

1 个答案:

答案 0 :(得分:3)

要获得SessionList[action.payload.Id]的结果,您需要将SessionList初始化为对象而不是数组。然后,您可以进行相应的更新。

   const initialState = {
      SessionList: {},
   }

   case "UPDATE_SESSION":
            state = {
                ...state,
                SessionList: Object.keys(state.SessionList).reduce((acc, id) => {
                    if (id === action.payload.Id) {
                      acc[id] = action.payload;
                    } else {
                      acc[id] = state.SessionList[id];
                    }

                    return acc;
                  }, {});
            };

更新

根据请求here,以下是 add update replace delete 处理程序而不将SessionList更改为对象。

const initialState = {
     SessionList: [],
}

注意: action.payload(无论使用在哪里)都是会话对象。

添加

state = {
    ...state,
    SessionList: [...state.SessionList, action.payload];
};

更新

state = {
    ...state,
    SessionList: state.SessionList.map((session) => {
        if (session.Id === action.payload.Id) {
           return Object.assign({}, session, action.payload);
        }

        return session;
    })
};

替换

state = {
    ...state,
    SessionList: state.SessionList.map((session) => {
        if (session.Id === action.payload.Id) {
           return action.payload;
        }

        return session;
    })
};

删除

state = {
    ...state,
    SessionList: state.SessionList.filter((session) => session.Id !== action.payload.Id)
};