为什么'这个'在Promise调用中未定义

时间:2018-06-07 17:47:14

标签: javascript reactjs

我不明白发生了什么

componentDidMount() {
    console.log('componentDidMount');
    //const self = this; 
    let _id = this.props.match.params.id.toUpperCase();

    if (_id != this.state.id.toUpperCase()) {

        axios.get('/data/pricemultifull?fsyms=' + _id + '&tsyms=USD')
            .then(response => {
                // let _currentcoin = { ...resp.data.RAW.BTC.USD, ticker: _id };
                this.setState({ id: _id }); //this == undefined
            });
    }
}

我可以收到回复,但this始终未定义且我无法setState。我使用箭头功能,我认为这是范围'这个'到组件级别。我可以通过在发出请求之前创建一个新var并设置'this'来修复它。我知道this应该正常工作。我错过了什么?

我的整个组件

import React, { Component } from 'react';
import axios from '../../axios';


class CoinViewer extends Component {

state = {
    coin: {},
    hasLoaded: false,
    id: ''
}

componentDidMount() {
    console.log('componentDidMount');
    //const self = this; 
    let _id = this.props.match.params.id.toUpperCase();

    if (_id != this.state.id.toUpperCase()) {

        axios.get('/data/pricemultifull?fsyms=' + _id + '&tsyms=USD')
            .then( resp => {
                // let _currentcoin = { ...resp.data.RAW.BTC.USD, ticker: _id };
                this.setState({ id: _id });
            });
    }
}

componentWillMount() {

}

componentWillUpdate() {


}

componentDidUpdate() {

}

getCompleteCoinData(_id) {

}


render() {


    return (
        <div>
            CoinViewer Component: {this.state.id} sads
        </div>
    )
}

}

导出默认CoinViewer

3 个答案:

答案 0 :(得分:3)

:编辑 哇,下面的内容有点真实,但真正的问题是你没有初始化状态。 https://reactjs.org/docs/react-component.html#constructor

constructor() {
  super();
  this.state = {
    coin: {},
    hasLoaded: false,
    id: ''
  }
}

您可以使用词法作用域并像这样修复,这是一种保护this的流行模式。

基本上,当你使用来自其他库/ API的promises或函数时,你不知道他们在回调函数中设置了它们的上下文。

为了使用您想要的上下文,您需要将需要保存的上下文保存在范围内的变量中,并在_this引用它,而不是指向上下文this。我建议你阅读“你不知道js&#39;进一步理解这个概念。

componentDidMount() {
  console.log('componentDidMount');
  const _this = this; 
  let _id = _this.props.match.params.id.toUpperCase();

  if ( _id != _this.state.id.toUpperCase() ) {
    axios.get('/data/pricemultifull?fsyms=' + _id + '&tsyms=USD')
      .then(response => {
        _this.setState({ id: _id }); //this == undefined
      });
  }
}

答案 1 :(得分:0)

解决方案1:箭头功能..

#:kivy 1.10.0

<Label>:
    font_size: 30


<MainScreen>:

    Label:
        canvas.before:
            Color:
                rgba: 1, 0, 0, 1    # red
            Rectangle:
                size: self.size
                pos: self.pos
        text: "Connections"
        size_hint: 0.1, 0.1
        pos_hint: {"left": 0.2, "top": 1}
        color: 1,0,1,1
        outline_color: 1,0,1,1


    Label:
        canvas.before:
            Color:
                rgba: 0, 0, 1, 1    # blue
            Rectangle:
                size: self.size
                pos: self.pos
        text: "Modules"
        size_hint: 0.1, 0.1
        pos_hint: {"right": 0.2, "top": 1}

解决方案2:绑定

requestSuccess = (resp) => {
  // let _currentcoin = { ...resp.data.RAW.BTC.USD, ticker: _id };
  this.setState({ id: _id });
}

componentDidMount() {
  console.log('componentDidMount');
  //const self = this; 
  let _id = this.props.match.params.id.toUpperCase();
  if (_id != this.state.id.toUpperCase()) {
     axios.get('/data/pricemultifull?fsyms=' + _id + '&tsyms=USD')
       .then(this.requestSuccess);
  }
}

答案 2 :(得分:0)

  

使用React.js时,您可能会遇到一个问题   可以从promise内部访问 this 。   诺言。旧的方法是设置 self = this   参考,尽管这可行,但推荐的解决方案是   与ES6更内联的是在此处使用箭头功能:

class Component extends React.Component { 
  componentDidMount() {
    let component = this;
    axios.get('http://…').then(function(data) {
      component.setState( { name: data.blah } );
    });
  }
}
  

如上所述,箭头语法是允许使用的更聪明的方法   正如我们所看到的,它引用了React.Component类   下方:

class Component extends React.Component { 
  componentDidMount() {
    axios.get('http://…').then(data => {
      this.setState( { name: data.blah } );
    });
  }
}
  

请注意,不要使用   function(data){// body},   我们使用了data => {// body},在这种情况下,该引用将无法获得promise实例。