无法在本机功能中读取“this”

问题描述 投票:0回答:3

我试图从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不是一个函数(评估'_this3.setState({user_email:json.email})')]

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

react-native this facebook-login fbsdk
3个回答
0
投票

原因是由于嵌套箭头功能导致this丢失。您可以定义一个变量来保存对this的引用,并使用that代替。

您可以通过在函数内执行以下操作来解决此问题

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

您还应确保通过使其成为箭头函数或通过在构造函数中绑定它来绑定函数。


1
投票

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

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

这应该工作!


1
投票

不要使用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获取电子邮件和朋友,但你不是要求权限,这是故意的吗?我还是添加了权限。

© www.soinside.com 2019 - 2024. All rights reserved.