использование Socket.io с React и Redux для обработки сотен обновлений в секунду

У меня есть список элементов, которые являются объектами данных с сервера (около 1000), которые мне нужно отсортировать, отфильтровать, поместить в Redux и подключить к компоненту таблицы React. Я использую socket.io для прослушивания обновлений, которые отправляют эти отдельные объекты данных, которые затем необходимо вычислить в таблице. они могут быть обновлением, новым или удалением существующего.

Итак, мой вопрос: как лучше всего управлять таким количеством входящих событий данных сокетов? я должен просто задушить их, прежде чем я обновлю их до моего состояния редукции? я не хочу постоянно обновлять свое состояние редукции, иначе компонент моей таблицы будет слишком сильно перерисовываться.

мой другой вариант: я могу запросить текущий обновленный список всех «активных» данных и просто игнорировать события обновления. поэтому, возможно, каждые несколько секунд просто обновляйте всю таблицу всеми последними данными вместо того, чтобы пытаться управлять сотнями обновлений в секунду.


person Community    schedule 23.06.2018    source источник
comment
Можете ли вы добавить некоторые подробности о вашей нынешней стратегии? Наряду с примерами кода компонента, отображающего таблицу.   -  person Rishul Matta    schedule 23.06.2018


Ответы (1)


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

Ваш редуктор будет выглядеть примерно так в случае действия создания элемента:

export default (state = {}, action) => {
  switch (action.type) {
    case ActionsTypes.CREATE_START:
      // make the temporary changes

    case ActionsTypes.CREATE_SUCCESS:
      // update the previous temporary id with a proper id

    case ActionsTypes.CREATE_FAILURE:
      // delete the temporary changes

    default:
      return state;
  }
};

А ваши действия такие:

const ActionLoading = item => ({
  type: ActionsTypes.CREATE_START,
  item,
});

const ActionSuccess = item => ({
  type: ActionsTypes.CREATE_SUCCESS,
  item ,
  createdItem,
});

const ActionFailure = item => ({
  type: ActionsTypes.CREATE_FAILURE,
  item,
});

export default todo => (dispatch) => {
  dispatch(ActionLoading(item)); // add the item to your state

  const updatedTodo = await TodoClient.create(todo)

  if (updatedTodo) {
    dispatch(ActionSuccess(item, createdItem)) // update the temp item with a real id
  } else {
    dispatch(ActionFailure(item)) // remove the temporary item 
  }
};

Обязательно, чтобы вы давали временные идентификаторы данным, которыми вы управляете, ради производительности и позволяли правильно реагировать на элементы, отображаемые на картах. Лично я использую uniqueId от lodash.

Вам также придется реализовать это поведение для обновлений и удалений, но в основном это то же самое:

  • сохраните изменения, обновите свой объект, не дожидаясь API, и отмените изменения в случае сбоя.
  • удалите свой объект, не дожидаясь API, и вставьте его обратно в случае сбоя.

Это даст ощущение реального времени, так как все будет обновляться мгновенно и возвращаться только в случае неуправляемых ошибок. Если вы достаточно доверяете своему бэкенду, это правильный путь.

РЕДАКТИРОВАТЬ: только что увидел ваше обновление, вы можете придерживаться этого способа изменения данных (или обычного способа обновления состояния в случае успеха), но чтобы избежать слишком большой сложности и времени рендеринга, убедитесь, что вы храните свои данные, используя keyBy. Как только ваши элементы будут сохранены в виде массива объектов с ключом их идентификатора, вы сможете добавлять, удалять и изменять их со сложностью O (1). Кроме того, react поймет, что ему не нужно повторно отображать весь список, а только один обновленный элемент.

person Eld0w    schedule 23.06.2018