我遇到了一个异步问题,希望可以得到帮助。我得到的错误是
index.js:2178 Warning: Can't call setState (or forceUpdate) on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
in CreateRoomPage (created by Route)
此错误的位置在此函数内。找到两个位置,该位置显示loginPromise.then和位于函数底部的setState。我目前正在有人点击时调用此功能。
createUser(e) {
if (this.state.username === "") {
e.preventDefault();
this.setState({
errors: "Username can't be blank"
});
return;
}
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 => {
let db = firebase.database();
let playersRef = db.ref(`Room/${this.state.roomId}/players`);
playersRef.child(`${id}`).set(`${this.state.username}`);
let player = db.ref(`Room/${this.state.roomId}/players/${id}`);
player.onDisconnect().remove();
let allPlayers = db.ref(`Room/${this.state.roomId}/all-players`);
allPlayers.child(`${id}`).set(true);
let allPlayer = db.ref(`Room/${this.state.roomId}/all-players/${id}`);
allPlayer.onDisconnect().remove();
let scoreBoard = db.ref(`Room/${this.state.roomId}/scoreBoard`);
scoreBoard.child(`${this.state.username}`).set(0);
let playerScore = db.ref(
`Room/${this.state.roomId}/scoreBoard/${this.state.username}`
);
playerScore.onDisconnect().remove();
let creator = db.ref(`Room/${this.state.roomId}`);
creator.child("creator").set(`${id}`);
db.ref(`Room/${this.state.roomId}`)
.child("gameStarted")
.set(false);
this.setState({
username: "",
errors: ""
});
});
我花了将近3个小时来解决这个问题。我希望有人可以教我我在哪里出错。我尝试使用一种本地状态,其中一旦componentDidMount它将像这样卸载后将本地状态更改为true,然后将其更改为false:
componentDidMount() {
this.setState({ isMounted: true }, () => {
if (this.state.isMounted) {
let db = firebase.database();
let roomRefKey = db.ref("Room").push().key;
this.setState({
roomId: roomRefKey
});
}
});
}
下面是引发此类错误的另一个地方
createUser(e) {
e.preventDefault();
if (
this.state.username.length === 0 &&
this.state.accesscode.length === 0
) {
this.setState({
errors: {
username: "Username can't be blank",
accesscode: "Access Code can't be blank"
}
});
return;
}
if (this.state.username.length === 0) {
this.setState({
errors: { username: "Username can't be blank", accesscode: "" }
});
return;
}
if (this.state.accesscode.length === 0) {
this.setState({
errors: { username: "", accesscode: "Access Code can't be blank" }
});
return;
}
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 => {
let db = firebase.database();
let playersRef = db.ref(`Room/${this.state.accesscode}/players`);
playersRef.child(`${id}`).set(`${this.state.username}`);
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}`
});
});
}