2017-10-17 23 views
0

请问我的反应类,我试图更新我的状态,但我得到这个错误“无法读取属性setState的未定义”..我已经尝试每一个解决方案在线,但没有运气'this.setState'有什么问题

这里是代码

export default class PageBackground extends Component{ 
    constructor(props) { 
      super(props); 

      this.state={ 
       lat   :'nothing', 
       longi  :'' 
      }; 
      this.getLocation=this.getLocation.bind(this); 
      } 


     componentWillMount() { 
      this.getLocation(); 
     } 
     getLocation() { 

      fetch('http://freegeoip.net/json/') 
      .then((res)=>res.json()) 
      .then(function (objec){this.setState({lat:objec.latitude,longi:objec.longitude});}) 
      .catch((err)=>console.log("didn't connect to App",err)) 
      console.log(this.state.lat) 
     } 

     render(){ 
      return(
       <p>{this.state.lat}</p> 
       ) 
      } 
     } 
+0

您是否获得控制台日志? – buoyantair

+0

我认为'this'是在函数的上下文中。也许你应该尝试'that = this'和'that.setState' – AnkitG

+0

有litterally一百万重复这个非常错误。我很惊讶你没能找到他们中的任何一个。 – Chris

回答

5

function() { ... }语法不会维持从上下文this参考。使用箭头函数:

then(() => { 
    this.setState({lat: objec.latitude, longi: objec.longitude}) 
}) 

另一种选择是function() { }后添加.bind(this)

或者,只保存this一个局部变量,并用它在函数内部:

var self = this; 
fetch('http://freegeoip.net/json/') 
     .then((res)=>res.json()) 
     .then(function (objec){self.setState({lat:objec.latitude,longi:objec.longitude});}) 
     .catch((err)=>console.log("didn't connect to App",err)) 
     console.log(this.state.lat) 

然而,箭头功能都是一模一样介绍了这样那样的问题。

+0

非常感谢你。这工作,但我想知道为什么?我阅读箭头功能不能很好地与'这'''为什么这种情况不同? –

+0

为什么我们甚至必须绑定我们在构造函数中创建的es6类中的所有方法? –

+1

@JohnAnisere第一个问题的答案是箭头函数从周围的代码中捕获'this',因此您不必手动将'this'绑定到它们。他们以你期望的方式工作。另一个问题更复杂。当类方法用作“松散”(第一类)函数时,您正在讨论这个问题。这些方法不会自动绑定到它们的实例,而必须手动绑定。 – Sulthan

1

尝试了这一点:

getLocation() { 
      var self = this; 
      fetch('http://freegeoip.net/json/') 
      .then(function (objec) { 
       console.log(objec); 
       self.setState({lat: objec.latitude, longi: objec.longitude}) 
      }) 
      .catch(function (error) { 
       console.log(error); 
      }); 
     } 
1

这里的问题是,你想在不同的范围accesss this

每当我们通过一个function() {}作为回调,它会创建它自己的范围。 改为使用箭头函数。

() => { 'your code here'; } 

箭头函数共享其父项的范围。

getLocation =() => { 
    fetch('https://freegeoip.net/json/') 
     .then(res => res.json()) 
     .then((objec) => { 
      this.setState({ lat: objec.latitude, longi: objec.longitude }); 
     }) 
     .catch(err => console.log("didn't connect to App", err)); 
    console.log(this.state.lat); 
} 
+0

非常感谢你.. –