簡體   English   中英

在React.js中使用異步回調函數時無法讀取狀態

[英]Cannot read state when using async callbacks function in React.js

所以我從stackoverflow的帖子中復制了這個函數,我的目標是能夠在注冊后立即更新數據庫和配置文件信息,然后移動到不同的路由,結果就像我期望的那樣工作但是我無法再訪問在回調中的狀態,可以請有人協助我調試此代碼:

  signup = (e) => {
    this.setState({ loading: true });
    e.preventDefault();
    fire.auth().createUserWithEmailAndPassword(this.state.email, this.state.password)
      .then((userCredentials) => {
        if (userCredentials.user) {
          userCredentials.user.updateProfile({
            displayName: this.state.username,
            photoURL: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQdVmHPt9SajdsWlAZWzqRXkd-SzmmO9bBUV45fLnw5giijsty3OA',
          }).then((s) => {
            fire.database()
              .ref(`master/${userCredentials.user.displayName}/setup/`)
              .update({
                bio: 'Be original',
              })
              .then(() => {
                window.location.reload();
              });
          })
        }
      })
      .catch(function (error) {
        console.log(error);
        this.setState({ signupError: true, loading: false, });
      });
  }

catch中發生錯誤(錯誤)

TypeError:無法讀取未定義的屬性“setState”

我懷疑這個問題來自使用多個.then

JS功能都有自己的this方面。

在您的情況下,您在回調中使用this上下文。 反應組件的this上下文將在回調中丟失。 這就是catch塊無法識別setState方法的原因

為了保持並使用this回調內部情況下,分配this一個local variable (named the variable as self in below example) ,並訪問其回調中。

  signup = (e) => {
        var self= this;
        this.setState({ loading: true });
        e.preventDefault();
        fire.auth().createUserWithEmailAndPassword(this.state.email, this.state.password)
          .then((userCredentials) => {
            if (userCredentials.user) {
              userCredentials.user.updateProfile({
                displayName: this.state.username,
                photoURL: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQdVmHPt9SajdsWlAZWzqRXkd-SzmmO9bBUV45fLnw5giijsty3OA',
              }).then((s) => {
                fire.database()
                  .ref(`master/${userCredentials.user.displayName}/setup/`)
                  .update({
                    bio: 'Be original',
                  })
                  .then(() => {
                    window.location.reload();
                  });
              })
            }
          })
          .catch(function (error) {
            console.log(error);
            self.setState({ signupError: true, loading: false, });
          });
      }

你也可以使用arrow functionsarrow functions沒有自己的this上下文,所以你將能夠訪問this上下文的outerscope

.catch((error)=> {
   console.log(error);
   this.setState({ signupError: true, loading: false, });
});

thiscatch中不是你的類,在正常函數和箭頭函數之間看到不同。 有兩種方法可以解決您的問題。

  • 第一:使用箭頭功能
.catch(function (error) {
  console.log(error);
  this.setState({ signupError: true, loading: false, });
});
  • 第二: this設置局部self變量
signup = (e) => {
  this.setState({ loading: true });
  e.preventDefault();
  const self = this; // It can be what ever you want, `self` is the most popular
  ...
}

然后

.catch(function (error) {
  console.log(error);
  self.setState({ signupError: true, loading: false, });
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM