简体   繁体   English

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

[英]How to immutably update/replace React Redux State with a double nested array of objects?

My redux state has a SessionList which is an array of SessionObjects, and each SessionObject has an array of HandObjects. 我的redux状态有一个SessionList,它是一个SessionObjects数组,每个SessionObject都有一个HandObjects数组。

I use state to update individual SessionObjects by adding new HandObjects, however I want to update the redux store with my updated SessionObject (immutably, if possible). 我使用state通过添加新的HandObject来更新单个SessionObjects,但是我想用我更新的SessionObject更新redux存储(如果可能的话,不可变的)。

the index of the SessionObject within SessionList is action.payload.Id (I think? i will show my SessionObject constructor) SessionList中SessionObject的索引是action.payload.Id(我想?我将展示我的SessionObject构造函数)

**Adding Sessions works just fine, and I only update a Session with the session already in the store **添加会话工作正常,我只使用商店中已有的会话更新会话

I have tried every link that I can find, but my code is just different enough that I can't seem to update my SessionList correctly. 我已经尝试了所有可以找到的链接,但是我的代码与我的代码完全不同,我似乎无法正确更新我的SessionList。

my reducer, with the initial state store.js (where my reducers are) 我的reducer,初始状态为store.js(我的reducer是)

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 constructor Session.js 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", []);

*in case i am doing this wrong, I call (Session.js) *如果我这样做错了,我打电话(Session.js)

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

from a stack-navigator child component. 来自stack-navigator子组件。
then in the parent component, I call (Home.js) 然后在父组件中,我调用(Home.js)

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

With my dispatcher looking like: (Home.js) 我的调度员看起来像:(Home.js)

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

From testing, I am somewhat sure my reducer is getting called correctly. 从测试中,我有点确定我的减速器被正确调用。

I want to replace the SessionObject with action.payload in the correct index of the SessionList. 我想在SessionList的正确索引中用action.payload替换SessionObject。

EDIT * 编辑 *

Session.js 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
    };

The state in Session.js is a SessionObject Session.js中的状态是SessionObject

To achieve a result of SessionList[action.payload.Id] , you need to initialise SessionList as an object and not an array. 要实现SessionList[action.payload.Id]的结果,需要将SessionList初始化为对象而不是数组。 Then you can update accordingly. 然后你可以相应地更新。

   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;
                  }, {});
            };

Update 更新

As requested here , following are the add , update , replace and delete handlers without changing SessionList to an object. 根据此处的要求,以下是添加更新替换删除处理程序,而不将SessionList更改为对象。

const initialState = {
     SessionList: [],
}

Note: action.payload (wherever used) is a session object. 注意: action.payload (在任何地方使用)是一个会话对象。

Add

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

Update 更新

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

        return session;
    })
};

Replace 更换

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

        return session;
    })
};

Delete 删除

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM