I am using an arrow function to bind this
inside a React component. Please see the handleChange()
function below. When I put a breakpoint inside the arrow function, I find something very strange: this
is defined, but this.props
is undefined
. In spite of all this, this.props.onChange()
is properly invoked!!! Is there an explanation for this strange behavior?
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 On the other hand, the render()
method behaves normally - this.props
is defined.
Update
Here's the transpiled code produced by Babel:
_this.handleChange = function(event) {
var value = event.target.value;
_this.props.onChange(value);
}
More likely than not, you're being tricked by babel.
Since you're using a babel-preset < 2017, the transpilled code for:
class A {
method = () => {
this.prop.a();
};
}
would look something like :
var A = function A() {
var _this = this;
this.method = function () {
_this.prop.a();
};
};
Looking at the code above, both _this
and this
within method
are seemingly pointing to the class instance (because this
in a function called as a method of an object binds to that object ).
However, in JS this
is a dynamic property so we cannot statically determine its value in a predictable fashion just by reading the code; we have to run it.
This means that the this
inside handleChange
isn't necessarily the same this
you're expecting. It depends on how handleChange
is called. However, no matter how we call handleChange
, _this
won't be affected (hence one reason why Babel does this)
In your particular code, you are passing handleChange
to the onChange
event handler for TextField
, which will override this
to be undefined
by default.
React event handlers override the context to undefined
(by calling the handler as a plain function ):
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>
This means that in handleChange
, this
is bound by whatever TextField
sets it to while _this
still points to the instance of MyComponent
.
Hence everything still works (because _this
is correct), but this
is most likely undefined
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.