繁体   English   中英

this.props在React Component中的箭头函数中显示为undefined

[英]this.props shows as undefined in an arrow function within React Component

我使用的是箭头功能绑定this一个阵营组件中。 请参阅下面的handleChange()函数。 当我在箭头函数中放置一个断点时,我发现了一些非常奇怪的东西: this是定义的,但是this.propsundefined 尽管如此,还是正确调用了this.props.onChange() 对这种奇怪的行为有解释吗?

class MyComponent extends React.Component {
    render() {
        const { someProp } = this.props;

        // <TextField> is an input component from Material UI library
        return (
            <TextField
                onChange={this.handleChange}
            />
        );
    }

    handleChange = event => {
        const value = event.target.value;
        this.props.onChange(value);
    };
}

PS另一方面, render()方法正常运行 - 定义了this.props

更新

这是Babel生成的转换代码:

_this.handleChange = function(event) {
    var value = event.target.value;
    _this.props.onChange(value);
}

更可能的是,你被巴贝尔欺骗了。

由于您使用的是babel预设的<2017,因此已翻译的代码为:

class A {
  method = () => {
    this.prop.a();
  };
}

看起来像是这样的

var A = function A() {
  var _this = this;

  this.method = function () {
    _this.prop.a();
  };
};

看看上面的代码, method中的_thisthis似乎都指向了类实例(因为this在一个被称为对象方法的函数中绑定到该对象 )。

但是,在JS中, this是一个动态属性,因此我们不能仅通过读取代码以可预测的方式静态地确定其值。 我们必须运行它。

这意味着, this里面handleChange是不一定相同this你期待。 这取决于handleChange的调用方式。 但是,无论我们如何调用handleChange_this都不会受到影响(因此Babel _this一个原因)

在您的特定代码,您传递handleChangeonChange事件处理TextField ,这将覆盖thisundefined默认。

React事件处理程序将上下文覆盖为undefined (通过将处理程序作为普通函数调用 ):

 ReactDOM.render( <input onChange={logThis} placeholder="Start typing" />, document.querySelector('#example') ) function logThis() { console.log(this); } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id="example"></div> 

这意味着在handleChangethis受到TextField设置的限制,而_this仍然指向MyComponent的实例。

因此,一切仍然有效(因为_this是正确的),但是this是最有可能的undefined

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM