Как добавить элемент массива во вложенный объект редуктора? - PullRequest
0 голосов
/ 12 марта 2019

Я пытаюсь создать приложение для чата, используя firebase, response-native и redux.У меня есть коллекция сообщений, которая очень проста, как вы можете видеть ниже.

Firebase - Структура данных

"messages": {
    "-LZtqlYn2WB_1E-u4gUk-LZtqlYn2WB_1E-u4gUo": {
      "-LZv3-yzpZ88lCLkGyRT": {
        "createdAt": 1551474102199,
        "receiverId": "-LZtqlYn2WB_1E-u4gUo",
        "senderId": "-LZtqlYn2WB_1E-u4gUk",
        "text": "alls"
      }
    },
    "-LZtqlYn2WB_1E-u4gUo-L_8ymxVU_bS8r9Rux4y": {
      "-L_8z5l0mNgJodbdh07O": {
        "createdAt": 1551724473404,
        "receiverId": "-LZtqlYn2WB_1E-u4gUo",
        "senderId": "-L_8ymxVU_bS8r9Rux4y",
        "text": "asfasfsf"
      }
    }
  }

В случае, если вы не заметили, сообщения имеют длинный уникальный идентификатор, который являетсякомбинация receiveId и senderId.Я называю это dialogId .

Что я хочу?

Итак, допустим, у нас есть пользователь, у которого есть два разговора между другими пользователями.Я хочу сохранить разговоры этого пользователя в редукторе в виде массива объектов , обозначенных Идентификатор разговора .

Действие Redux

export const addMessage = (id, data) => ({
  type: MESSAGE_RECEIVED,
  id,
  data,
});

export const fetchMessages = (conversationId, userId) => (dispatch) => {
  dispatch(fetchingMessages());

  const rootRef = firebase.database().ref();

  rootRef
    .child('messages')
    .child(conversationId)
    .on('child_added', (snapshot) => {
      const message = snapshot.val();

      dispatch(
        addMessage(conversationId, {
          id: snapshot.key,
          date: moment(message.createdAt),
          isReceiver: message.receiverId === userId,
          message: message.text,
        }),
      );
    });
};

ReduxРедуктор

import { MESSAGE_RECEIVED } from '../constants';

const initialState = {
  payload: {},
  isLoading: false,
};

export default function messagesReducer(state = initialState, action) {
  switch (action.type) {
    case MESSAGE_RECEIVED:
      return {
        ...state,
        payload: {
          ...state.payload,
          [action.id]: [...state.payload[action.id], action.data],
        },
      };

    default:
      return state;
  }
}

Моя проблема

У меня проблемы с редуктором сообщений.Я думаю, у меня нет четкой информации об операторе спреда.Это то, что я получаю, когда запускаю свой код.

TypeError: Invalid attempt to spread non-iterable instance

Что я ожидаю от выхода редуктора

{
    "isLoading": false,
    "payload": {
        "-LZtqlYn2WB_1E-u4gUk-LZtqlYn2WB_1E-u4gUo": [
            {
                "id": "-L_X_0ekmluKjxG8gaje",
                "isReceiver": true,
                "message": "hi!"
            },
            {
                "id": "-LZv3RaUTUD6KQczYGJX",
                "isReceiver": false,
                "message": "hey!"
            }
        ],
        "-LZtqlYn2WB_1E-u4gUo-L_8ymxVU_bS8r9Rux4y": [
            {
                "id": "LZv3RaUTRY6KQxzYMJL",
                "isReceiver": false,
                "message": "hi!"
            }
        ]
    }
}

Спасибо!

1 Ответ

0 голосов
/ 12 марта 2019

Я абсолютный идиот. После того, как tarzen спросил меня о значении state.payload [action.id], я понял, что могу просто написать оператор if. Вот рабочий код редуктора:

import { MESSAGE_RECEIVED } from '../constants';

const initialState = {
  payload: [],
  isLoading: false,
};

export default function messagesReducer(state = initialState, action) {
  switch (action.type) {
    case MESSAGE_RECEIVED: {
      if (state.payload[action.id]) {
        return {
          ...state,
          isLoading: false,
          payload: {
            ...state.payload,
            [action.id]: [...state.payload[action.id], action.data],
          },
        };
      }

      return {
        ...state,
        isLoading: false,
        payload: {
          ...state.payload,
          [action.id]: [action.data],
        },
      };
    }
    default:
      return state;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...