2017-05-04 83 views
0

我越來越多次警告陣營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

回答

0

這可能關係到你的組件連接到終極版 事實爲好,這意味着有另一個實例(這是未安裝),這是 聽插座。 - 我的猜測是試圖斷開redux和 看看是否有幫助。在任何情況下,我都會將套接字和可選的零件移動到容器組件上,這個組件上的組件太多了,無法輕鬆進行調試! - 帕特里克

謝謝帕特里克!

相關問題