阵营Socket.io:只能更新一安装或安装组件

问题描述:

我越来越多次警告阵营Socket.io:只能更新一安装或安装组件

警告:的setState(...):只能更新一安装或安装组件。这通常意味着您在卸载的组件上调用了setState()。这是一个没有操作。请检查RoundView组件的代码。

和它指向一个socket.io线

socket.on(
     'rankings', 
     (payload) => this.setState({ 
     totals: payload.totals, 
     scores: payload.scores 
     },this.updateRoundProgress) 
    ); 

但分量明显安装,一切似乎运作正常,当拍摄的“排名”事件的状态被更新就好了。完整的代码如下:

https://github.com/JellyKid/ballsavr/blob/master/Frontend/app/components/user/RoundView.jsx

import React from 'react'; 
import handleFetch from '../../helpers/handleFetch'; 
import { Grid, Col, PageHeader } from 'react-bootstrap'; 
import { connect } from 'react-redux'; 
import update from 'immutability-helper'; 

import ConfirmScores from './view/ConfirmScores'; 
import Rankings from './view/Rankings'; 
import Scores from './view/Scores'; 
import Group from './view/Group'; 
import Manage from './view/Manage'; 

const socket = require('socket.io-client')('/round',{ 
    path: '/api/socket.io', 
    autoConnect: false 
}); 

class RoundView extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     round: this.props.round || { 
     event: { 
      title: 'Loading...' 
     }, 
     name: "Please wait", 
     tables: [], 
     players: [] 
     }, 
     scores: [], 
     totals: [] 
    }; 

    this.refreshScores = this.refreshScores.bind(this); 
    this.updateRoundProgress = this.updateRoundProgress.bind(this); 
    } 

    componentDidMount(){ 
    this.handleSocket(); 
    let fetches = [ 
     handleFetch('GET',`/api/score/totals?round=${this.props.params.roundID}`), 
     handleFetch('GET',`/api/score/round?id=${this.props.params.roundID}`) 
    ]; 
    if(!this.props.round){ 
     fetches.push(handleFetch('GET', `/api/round/${this.props.params.roundID}`)); 
    } 
    return Promise.all(fetches) 
    .then(
     (res) => { 
     this.setState({ 
      totals: res[0].payload, 
      scores: res[1].payload, 
      round: this.props.round || res[2].payload 
     }); 
     } 
    ).catch((err) => {console.log(err);}); 
    } 

    handleSocket(){ 
    socket.open(); 
    socket.on(
     'connect', 
    () => socket.emit('join round', this.props.params.roundID) 
    ); 
    socket.on(
     'rankings', 
     (payload) => this.setState({ 
     totals: payload.totals, 
     scores: payload.scores 
     },this.updateRoundProgress) 
    ); 
    socket.on(
     'connect_error', 
    () => setTimeout(socket.open, 1000) 
    ); 
    } 

    updateRoundProgress(){ 
    if(this.props.player.admin){ 
     let scores = this.state.scores.filter((score) => score.confirmed).length; 
     let progress = Math.floor((scores/(this.state.round.tables.length * this.state.round.players.length))*100); 
     return this.setState(update(
     this.state, 
     {round: {progress : {$set: progress}}} 
    )); 
    } 
    } 

    refreshScores(){ 
    handleFetch('GET',`/api/score/round?id=${this.props.params.roundID}`) 
    .then(
     (res) => this.setState({scores: res.payload}) 
    ).catch((err) => {console.log(err);}); 
    } 

    componentWillUnmount(){ 
    socket.close(); 
    } 

    render(){ 
    let player = this.state.round.players.find((p) => p.user._id === this.props.player._id); 
    let groupName = (player) ? player.group : ""; 

    return (
     <Grid> 
     <Col md={6} mdOffset={3}> 
      <PageHeader> 
      {this.state.round.event.title}<br/><small>{this.state.round.name}</small> 
      </PageHeader> 
      <Rankings 
      totals={this.state.totals} 
      players={this.state.round.players} 
      player={this.props.player} 
      /> 
      <hr /> 
      <Group 
      group={groupName} 
      players={this.state.round.players} 
      /> 
      <hr /> 
      <Scores 
      player={this.props.player} 
      scores={this.state.scores} 
      round={this.state.round} 
      group={groupName} 
      /> 
      <hr /> 
      <ConfirmScores 
      scores={this.state.scores} 
      player={this.props.player} 
      /> 
      <hr /> 
      <Manage 
      round={this.state.round} 
      player={this.props.player} 
      /> 
     </Col> 
     </Grid> 
    ); 
    } 
} 

function mapStateToProps(state, ownProps) { 
    return { 
    round: state.rounds.find((round) => round._id === ownProps.params.roundID), 
    player: state.user 
    }; 
} 

export default connect(mapStateToProps)(RoundView); 

我关闭时,插座组件卸除。当组件卸载时我也尝试过日志记录,并且在这之前它不会卸载,那么为什么我会得到错误?

+0

你会不断得到这个警告? – Chris

+1

这可能与您的组件连接到Redux的事实有关,这意味着还有另一个实例(未挂载)正在监听套接字。 - 我的猜测是试图断开redux,看看是否有帮助。 在任何情况下,我会将套接字和可选的redux移动到一个容器组件,这个组件上有太多的事情要去调试它! – Patrick

+0

这是问题所在。我将socket.io部分分成了它自己的组件。谢谢! – JellyKid

这可能关系到你的组件连接到终极版 事实为好,这意味着有另一个实例(这是未安装),这是 听插座。 - 我的猜测是试图断开redux和 看看是否有帮助。在任何情况下,我都会将套接字和可选的零件移动到容器组件上,这个组件上的组件太多了,无法轻松进行调试! - 帕特里克

谢谢帕特里克!