【发布时间】:2018-08-16 12:30:38
【问题描述】:
我遇到了一个问题,我希望有人可以帮助解释这个错误出现的原因。当一个componentDidMount 我总是将isMounted 设置为true 和componentWillUnmount 时为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("before crash", 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 仍在 join-room 组件中运行,这就是为什么它在前往等候室组件时失败的原因?这基本上只在从加入房间按钮触发 createUser 时才会出现
也感谢大家的帮助。
【问题讨论】:
标签: javascript reactjs asynchronous