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

Posted

技术标签:

【中文标题】无法在反应本机功能中读取“this”【英文标题】:cannot read "this" in react native function 【发布时间】: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

【问题讨论】:

【参考方案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)
  )

【讨论】:

以上是关于无法在反应本机功能中读取“this”的主要内容,如果未能解决你的问题,请参考以下文章

反应本机应用程序 - 出现错误 app.js 无法读取未定义的属性“文件名”

使用firebase读取数据以反应本机

无法在本机反应中使用 fetch 执行 POST 请求

TypeError:无法读取反应中未定义的属性“减少”

无法在本机反应上构建 APK

使用 RNFS 在本机反应上读取 Json 文件