我遇到了一个问题,希望有人可以帮助解释出现此错误的原因。当componentDidMount设置为componentWillUnmount时,我始终将isMounted设置为true和false。现在,我有点困惑,因为在所附的图像中,我将console.logs放到了各处,以查看正在运行的内容。在该图像中,您可以看到该组件已安装,但失败了。Shows console.logs and error
当我打开错误消息时,有两个地方指出失败了。第一个是
gameStarted() {
let gameID = this.props.match.params.id;
let db = firebase.database();
db.ref(`Room/${gameID}`).on("value", snapshot => {
let collection = snapshot.val();
if (collection === null) {
return;
}
if (
collection["gameStarted"] === null ||
collection["gameStarted"] === undefined
) {
return;
}
let startGame = collection["gameStarted"];
console.log("before crash");
if (this.state.isMounted) {
console.log("before crash", this.state.isMounted);
this.setState(
{
startGame
},
() => {
console.log("Start Game Worked");
}
);
}
console.log("after crash");
});
}
从上图中,我们可以看到错误出现之前console.log(“崩溃前”,true)正在运行。我在这方面有点困惑,因为它应该工作,因为本地状态设置为true?没有?
下一个出现的错误是在另一个组件中。它的设置方式是,如果用户不属于候诊室,他们将被重定向到加入诊室组件。这是第二个错误显示为
的地方 const loginPromise = new Promise((resolve, reject) => {
firebase.auth().onAuthStateChanged(user => {
if (user) {
window.user = user;
resolve(user.uid);
} else {
firebase
.auth()
.signInAnonymously()
.then(user => {
resolve(user.uid);
})
.catch(err => {
console.log(err);
});
}
});
});
loginPromise.then(id => {
console.log("before crash", this.state.isMounted);
let db = firebase.database();
let playersRef = db.ref(`Room/${this.state.accesscode}/players`);
playersRef.child(`${id}`).set(`${this.state.username}`);
console.log("After crash", this.state.isMounted);
let player = db.ref(`Room/${this.state.accesscode}/players/${id}`);
player.onDisconnect().remove();
let allPlayers = db.ref(`Room/${this.state.accesscode}/all-players`);
allPlayers.child(`${id}`).set(true);
let allPlayer = db.ref(`Room/${this.state.accesscode}/all-players/${id}`);
allPlayer.onDisconnect().remove();
let scoreBoard = db.ref(`Room/${this.state.accesscode}/scoreBoard`);
scoreBoard.child(`${this.state.username}`).set(0);
let playerScore = db.ref(
`Room/${this.state.accesscode}/scoreBoard/${this.state.username}`
);
playerScore.onDisconnect().remove();
this.props.history.push({
pathname: `/waiting-room/${this.state.accesscode}`
});
});
}
尽管我不认为这是事实,因为在控制台内它仍然继续运行而不会崩溃。因此,当用户设置等候室URL时,如果他们不属于会议室,则将其重定向到联接室组件,在该联接室组件中,他们需要输入用户名才能返回游戏室组件。我知道这些重定向可能是问题,关于如何解决此setState卸载组件的任何建议?
[更新] 可能是因为Promise仍在联接室组件中运行,这就是为什么一旦进入等候室组件就会失败吗?这基本上仅在从加入房间按钮触发createUser后才会出现
也感谢您的所有帮助。
答案 0 :(得分:0)
您应先停止订阅事件,然后再卸载:
componentWillUnmount() {
let gameID = this.props.match.params.id;
let db = firebase.database();
db.ref(`Room/${gameID}`).off("value");
}
您的组件将停止接收更新事件,并且状态不会被更新