Как правильно рендерить тяжелый поток веб-сокетов в React? - PullRequest
0 голосов
/ 21 октября 2018

В настоящее время у меня есть что-то вроде этого:

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 вещей или около того ...

Сокет отправляет около 15 сообщений в секунду.Моя проблема: я не могу отображать сообщения в режиме реального времени!Это просто замерзает.Я думаю, что поток слишком быстрый?Есть предложения?

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

Ответы [ 2 ]

0 голосов
/ 21 октября 2018

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

Взгляните на 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 имеет кэш элементов. Дайте мне знать, если это помогает.

0 голосов
/ 21 октября 2018

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...