Дросселирование вызовов MapStatetoProps в подключенных компонентах - PullRequest
2 голосов
/ 18 июня 2020

У меня есть приложение React с магазином Redux, которое подключается к веб-сокету и отображает информацию пользователю в таблице. У меня есть промежуточное ПО Rx Js, которое подключается к веб-сокету и отправляет действия с содержимым. Затем они собираются в редукторе и сохраняются в моем состоянии. Затем я mapStateToProps для отображения данных в моих компонентах React.

Проблема в том, что обновления приходят быстрее, чем может быть рендеринг. Я мог получать 50 обновлений в секунду, и если бы я рендерил каждый раз, когда данные поступали в мое приложение, производительность была бы ужасной. Мне нужен способ уменьшить количество вызовов mapStatetoProps. У меня есть много компонентов, которые сопоставляются с этим состоянием, и на данный момент у меня есть 1 секунда дросселирования в shouldComponentUpdate для каждого из них. Было бы лучше, если бы я мог регулировать скорость один раз в секунду на более низком уровне, чтобы избежать дублирования logi c в каждом из моих компонентов. Я также не могу отбросить ни одно из 50 сообщений, которые я получаю в секунду, и просто взять самое последнее, потому что данные, необходимые пользователю, распределены по каждому сообщению. Есть идеи?

1 Ответ

0 голосов
/ 18 июня 2020

Проблема в том, что хранилище redux обновляется 50+ раз в секунду, поэтому компонент отображается 50+ раз в секунду. Вы хотите, чтобы магазин обновлялся каждые n секунд, но без потери данных. Это обычная проблема для высокочастотных данных; Обычно решение состоит в использовании кеша.

Таким образом, вам нужно кэшировать результаты, а затем каждые n секунды помещать sh кешированные сообщения в массив сообщений, а затем очищать кеш.

Это будет выглядеть примерно так.

your_websocket.on("new_message", message =>
  dispatch({ action: "ADD_TO_CACHE", message })
);

setInterval(() => {
    dispatch({ action: "PUSH_CACHE_TO_STATE" });
}, 1000);

const your_reducer = (state, action) => {
    /* -- snip -- */
    case "PUSH_CACHE_TO_STATE":
        newState.messages.push(...newState.messageCache);
        newState.messageCache = [];
        return newState;
    case "ADD_TO_CACHE":
        newState.messageCache.push(action.message);
        return newState;
}

Это поместит sh каждое новое сообщение в кеш, затем каждые 1000 миллисекунд кеш будет очищаться и помещаться в массив сообщений в вашем redux store.

Затем в вашем компоненте вы просто mapStateToProps вот так:

connect(store => ({ messages: store.messages }))(YourComponent);

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

...