发出socketio消息后,React app缓慢呈现缓慢

时间:2018-05-20 11:22:09

标签: javascript reactjs rendering

我有一个反应应用程序。代码确实可以正常工作但使用后。它开始变慢。等待一段时间后,您可以再次使用它。

当您按下按钮时,我会使用socketio发出消息。

多次使用后,函数调用需要更长的时间。

函数调用是websocket.js的一部分。然而,当你深入研究函数时,似乎反应渲染需要更长的时间。

需要花费大量时间的功能。

因此,反应需要花费大量时间来渲染视图。我只能认为我不删除会占用大量内存的东西,从而减慢渲染过程。在图片上,您看到它位于文件react-dom.development.js中,当它为生产构建时也会出现问题。

import React, { Component } from 'react';
import Card from './Card.js'

class Game extends Component {
  constructor(props) {
    super(props);
    this.state = {
      socket: this.props.socket,
      card: {
        "name": "",
        "cardValues": {}
      }
    }
    this.props.socket.emit("startGame");
  }
  render() {
    let {socket, card} = this.state;
    socket.on("startGame", (data) => this.setState({
        card: data["card"],
    }))
    socket.on("nextCard", (data) => this.setState({
        card: data["nextCard"],
    }))
    return (
      <div className="Game">
          <p>GAME</p>
          <Card socket={socket} card={this.state.card}/>
      </div>
    );
  }
}
export default Game;

此部分使用课程Card

import React, { Component } from 'react';

class Card extends Component {
  constructor(props) {
    super(props);
    this.state = {
      socket: this.props.socket,
    }
  }

  chooseCardValue = (value) => {
      this.state.socket.emit("chooseCard", {"cardValue": value});
  }

  render() {
    let card = this.props.card;
    return (
      <div className="Card">
          <h3 className="Country">{card["name"]}</h3>
          <ul>
            {
              Object.keys(card["cardValues"]).map((value, i) => {
                return <li key={i}><button onClick = {
                    this.chooseCardValue.bind(null, value)
                }>{value}: {card["cardValues"][value]}</button></li>
              })
            }
          </ul>
      </div>
    );
  }
}
export default Card;

这里定义了按钮。当您单击该按钮时,它会触发函数chooseCardValue,该函数会在一段时间后变慢。

为什么它变得那么慢,原因是什么?

我试图只包含可能相关的部分。这里提供了整个课程,以防万一:https://lpaste.net/3474101090415280128

1 个答案:

答案 0 :(得分:0)

您正在将套接字侦听器附加到render方法中。这意味着每次您的应用重新渲染时,您都会添加2个额外的侦听器。此外,在侦听器内部调用setState,它会触发重新渲染,从而添加另一个侦听器。

第一次收到消息时,您的应用会呈现一次,并添加一个监听器。 第二次收到消息时,您的应用将呈现两次(每个侦听器一次),您将添加2个侦听器。 第三次会有4次渲染。 然后8,16,32等。

基本上你需要做的是不在render方法中添加那些监听器。您可以尝试将它们移动到constructorcomponentDidMount方法,但实际上它应该位于组件树外部的某个位置。

为清楚起见,这些是我所说的话:

let {socket, card} = this.state;
socket.on("startGame", (data) => this.setState({
    card: data["card"],
}))
socket.on("nextCard", (data) => this.setState({
    card: data["nextCard"],
}))