Как правильно отрендерить поток тяжелых веб-сокетов в React?

У меня сейчас что-то вроде этого:

const socket = require('socket.io-client')('https://example.com');
(....)

// Listen to the channel's messages
socket.on('m', message => {
    // this is a Redux action that updates the state
    this.props.updateTrades(message);
});

Редуктор выглядит так:

        case actions.UPDATE_TRADES:
        return {
            ...state,
            trades: [
                ...state.trades,
                action.trade
            ]
        };

Я пробовал не использовать сокращение, а просто следующее:

        socket.on('m', message => {
            this.setState(state => {
                if (state.trades.length > 99) {
                    state.trades.splice(0, 1);
                }
                return {
                    trades: [
                        ...state.trades,
                        message
                    ]
            });
        });

Мне не нужно постоянно увеличивать мой массив trades. Я счастлив просто хранить около 100 предметов ...

Socket отправляет около 15 сообщений в секунду. Моя проблема: я не могу отображать сообщения в реальном времени! Просто зависает. Полагаю, поток слишком быстрый? Какие-либо предложения?

Заранее спасибо!

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
0
676
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Ну ... Я подумал об этом, но это показалось хакерским способом обойти это ... как setTimeout ... просто кажется неправильным ...?

PetSilv 21.10.2018 10:27
Ответ принят как подходящий

Дело в том, чтобы сделать минимально возможное, и когда сделки меняются, отрисовывайте только то, что изменилось, а не все элементы массива. Я использую технику, чтобы сохранить карту кеша уже нарисованных объектов obj, поэтому в методе визуализации я рендерить только новые входящие элементы.

Взгляните на https://codesandbox.io/s/wq2vq09pr7

class RealTimeList extends React.Component {
  constructor(props) {
    super(props);
    this.cache = [];
  }
  renderRow(message, key) {
    return <div key = {key}>Mesage:{key}</div>;
  }
  renderMessages = () => {
    //let newMessages=this,props.newMessage
    let newElement = this.renderRow(this.props.message, this.cache.length);
    this.cache.push(newElement);
    return [...this.cache];
  };
  render() {
    return (
      <div>
        <div> Smart List</div>
        <div className = "listcontainer">{this.renderMessages()}</div>
      </div>
    );
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { message: "hi" };
  }

  start = () => {
    if (this.interval) return;
    this.interval = setInterval(this.generateMessage, 200);
  };
  stop = () => {
    clearTimeout(this.interval);
    this.interval = null;
  };

  generateMessage = () => {
    var d = new Date();
    var n = d.getMilliseconds();
    this.setState({ title: n });
  };

  render() {
    return (
      <div className = "App">
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
        <button onClick = {this.start}> Start</button>
        <button onClick = {this.stop}> Stop</button>
        <RealTimeList message = {this.state.message} />
      </div>
    );
  }
}

У класса RealTime List есть кеш элементов. Сообщите мне, поможет ли это.

Это звучит интересно! любой код / ​​псевдокод, который помог бы мне добиться этого?

PetSilv 21.10.2018 12:31

Я обновил ответ и поместил рабочий пример в песочницу кода.

Guillermo Quiros 22.10.2018 00:10

Большое спасибо! Действительно полезно !! :) (не могу дать вам положительный голос, потому что у меня недостаточно репутации)

PetSilv 22.10.2018 20:04

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

Guillermo Quiros 22.10.2018 20:40

Другие вопросы по теме