链接的异步问题

时间:2018-08-15 17:15:22

标签: javascript reactjs asynchronous

我遇到了一个异步问题,希望可以得到帮助。我得到的错误是

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}`
      });
    });
  }

0 个答案:

没有答案