【问题标题】:cannot read "this" in react native function无法在反应本机功能中读取“this”
【发布时间】:2019-02-18 07:02:10
【问题描述】:

我正在尝试从 facebook 登录设置用户数据并将其存储在一个状态但发生错误。

Facebook 身份验证

_fbAuth(){
  LoginManager.logInWithReadPermissions(['public_profile']).then(function(res){
    if(res.isCancelled){
      console.log('login cancelled.')
    } else {
      AccessToken.getCurrentAccessToken().then(tokenData => {
        if(tokenData) {
          const { accessToken, userID } = tokenData;
          fetch('https://graph.facebook.com/v2.5/me?fields=email,name,friends&access_token=' + accessToken).then((response) => 
            response.json()).then((json) => {
              this.setState({ user_email: json.email })
            }).catch(() => {
              reject('ERROR GETTING DATA FROM FACEBOOK')
            }
          )
        }
      })
    }
  }, function(err){
    console.log(err)
  })
}

将数据注册到抛出此错误的状态:

[TypeError: undefined is not a function (评估 '_this3.setState({ user_email: json.email })')]

我应该如何在fetch() 响应中访问this

【问题讨论】:

    标签: react-native this facebook-login fbsdk


    【解决方案1】:

    在您的构造函数中添加这一行以将组件上下文绑定到函数范围。

    this._fbAuth = this._fbAuth.bind(this);
    

    这应该可行!

    【讨论】:

      【解决方案2】:

      不要使用bind 或旧的const that = this 解决方法。如果您完全切换到箭头功能,这会容易得多,我建议也使用 async/await。例如:

      _fbAuth = async () => {
          try {
              let resLogin = await LoginManager.logInWithReadPermissions(['public_profile', 'email', 'user_friends']);
              if(resLogin.isCancelled){
                  console.log('login cancelled.');
                  return;
              }
              let resTokenData = await AccessToken.getCurrentAccessToken();
              if(resTokenData) {
                  const {accessToken, userID} = resTokenData;
                  let resAPI = await fetch(`https://graph.facebook.com/v2.5/me?fields=email,name,friends&access_token=${accessToken}`);
                  resAPI = resAPI.json();
                  this.setState({user_email: resAPI.email});
              }
          } catch (err) {
              console.log(err);
          }
      };
      

      避免“回调地狱”,使用 async/await 看起来更简洁、更易于阅读。应该与 LoginManager 一起使用,因为它似乎返回了一个 Promise。我还在示例中添加了模板字符串,并在用户取消时添加了返回。不需要这样缩进整个 else 块。

      顺便说一句,您正在尝试使用 API 获取电子邮件和朋友,但您并没有要求权限,这是故意的吗?反正我已经加了权限。

      【讨论】:

      • 感谢您的详细解释。这是我第一次在应用程序上集成 fb,所以我只是复制其他代码并尝试一下。顺便说一句,投票指出这一点。 :)
      • 不客气!一个提示:不要只是复制/粘贴代码,确保你理解每一行:)
      【解决方案3】:

      原因是this由于嵌套的箭头函数而丢失了。您定义一个变量来保存对this 的引用,并改用that

      您可以通过在函数中执行以下操作来解决它

      _fbAuth = () => {
        const that = this;
        ...
        that.setState({ user_email: json.emal });
        ...
      }
      

      你还应该确保你已经绑定了你的函数,要么将它设为箭头函数,要么在构造函数中绑定它。

      【讨论】:

        【解决方案4】:
        _fbAuth(){
        
        const _this = this;  // add this line
        
          LoginManager.logInWithReadPermissions(['public_profile']).then(function(res){
            if(res.isCancelled){
              console.log('login cancelled.')
            } else {
              AccessToken.getCurrentAccessToken().then(tokenData => {
                if(tokenData) {
                  const { accessToken, userID } = tokenData;
                  fetch('https://graph.facebook.com/v2.5/me?fields=email,name,friends&access_token=' + accessToken).then((response) => 
                    response.json()).then((json) => {
                      _this .setState({ user_email: json.email }) // replace this with _this
                    }).catch(() => {
                      reject('ERROR GETTING DATA FROM FACEBOOK')
                    }
                  )
                }
              })
            }
          }, function(err){
            console.log(err)
          })
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-02-04
          • 2022-01-21
          • 2018-12-14
          • 1970-01-01
          • 1970-01-01
          • 2023-01-11
          • 1970-01-01
          相关资源
          最近更新 更多