为什么在承诺调用中未定义"this"



我不明白发生了什么

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.我正在使用一个箭头函数,我认为该函数将"this"范围限定为组件级别。我可以通过在发出请求之前创建一个新的 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>
)
}

}

导出默认硬币查看器

解决方案 1:箭头函数。

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:绑定

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 });
}.bind(this));
}
}

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

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

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

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

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

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
});
}
}

> 在使用 React .js 时,您可能遇到了一个问题 从承诺内部访问。在 承诺。旧方法是设置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 实例。

最新更新