阵营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);
我关闭时,插座组件卸除。当组件卸载时我也尝试过日志记录,并且在这之前它不会卸载,那么为什么我会得到错误?
答
这可能关系到你的组件连接到终极版 事实为好,这意味着有另一个实例(这是未安装),这是 听插座。 - 我的猜测是试图断开redux和 看看是否有帮助。在任何情况下,我都会将套接字和可选的零件移动到容器组件上,这个组件上的组件太多了,无法轻松进行调试! - 帕特里克
谢谢帕特里克!
你会不断得到这个警告? – Chris
这可能与您的组件连接到Redux的事实有关,这意味着还有另一个实例(未挂载)正在监听套接字。 - 我的猜测是试图断开redux,看看是否有帮助。 在任何情况下,我会将套接字和可选的redux移动到一个容器组件,这个组件上有太多的事情要去调试它! – Patrick
这是问题所在。我将socket.io部分分成了它自己的组件。谢谢! – JellyKid