在嵌套数组中反应 Redux Push 对象

React Redux Push object in nested array

如何从 reducer 推送新消息到连接数组中?我试图通过索引找到正确的连接然后推送它,但无法开始工作。 连接架构例如:

_id: 3213213,
messages:[...]

消息架构例如:

_id: 123213,
author: '12312321',
body: 'Hi!'

因此需要从连接数组中找到正确的连接,然后将其推送到该连接内的消息数组中

问题代码:

const messagesReducer = (state = [], action) => {
  switch (action.type) {
    case RECIEVE_CONNECTIONS:
      return action.payload;
    case UPDATE_MESSAGES:
      let index = state.findIndex(
      connection => connection._id === action.update.id
      );
      return [...state, state[index].messages.concat(action.update.message)];
   default:
    return state;
   }
};

export default messagesReducer;

你实际上并没有用这行更新状态:

return [...state, state[index].messages.concat(action.update.message)];

你实际上是在破坏你的 Redux 状态,因为 state 是一个连接列表,而这里你包含了连接的消息列表。

这是一个让你的状态相对不可变的例子(如果你想要完全不可变,你还需要克隆所有现有的连接/消息,在这个例子中我只是复制数组)

let index = state.findIndex(
  connection => connection._id === action.update.id
);
const conn = state[index];
const messages = [ ...conn.messages, action.update.message ];
const newState = state.slice();
newState[index] = { ...conn, messages };
return newState;
const messagesReducer = (state = [], action) => {
  switch (action.type) {
    case RECIEVE_CONNECTIONS:
      return action.payload;
    case UPDATE_MESSAGES:
      // identify the index to update
      const index = state.findIndex(
        connection => connection._id === action.update.id
      );

      // create the new list of messages for the connection
      const messages = state[index].messages.concat(action.update.message)

      // modify the connection at index without modifying state
      const modifiedConnection = Object.assign({}, state[index], { messages });

      // replace the connection at index with the modified connection containing the new message
      return Object.assign([], state, { [index]: modifiedConnection });

   default:
    return state;
   }
};

你很接近,但是当你真的想为特定连接添加到嵌套消息列表时,你正在添加到连接列表。

好的,我想我明白了。可能有点冗长,但我认为这样你会更好地理解它。这也是完全不可变的。

const messageToAdd = {
  _id: "xxx",
  body: "new message",
  author: "bar"
};

const index = state.findIndex(
  connection => connection._id === action.update.id
);

const connectionToUpdate = {
  ...state.slice(index, index + 1)[0]
};

const updatedMessagesArr = [
  ...connectionToUpdate.messages,
  messageToAdd
];

const updatedConnection = {
  ...connectionToUpdate,
  messages: updatedMessagesArr
};

return = [
  ...state.slice(0, index),
  updatedConnection,
  ...state.slice(index + 1)
];