I have a function handleInputChange
that I want to write once (DRY principle), but apply it to many of my React classes. However, binding to this
in the constructor doesn't work.
handleInputChange = (key, value) => {this.setState(key: value)}
class Login extends Component {
constructor(props) {
super(props);
this.state = {
loginBox: {
username: "",
password: ""}
}
this.handleInputChange = handleInputChange.bind(this) // DOESN't WORK
}}
Why does the above method not work? The error I get is:
Uncaught TypeError: Cannot read property 'setState' of undefined
I am currently using this function wrapper workaround, but I'd rather bind the function directly.
handleInputChange = (_this) => () => (key, value) => {_this.setState(key: value)}
class Login extends Component {
...
this.handleInputChange = (key, value) => handleInputChange(this)(key, value)
You can't bind this
in arrow functions. this
falls through to the parent scope.
You could make it a non-arrow function:
function handleInputChange(key, value) { this.setState(key: value) }
But I'd suggest making it a method on the class. Defining a function that references this
is tricky to read, because you never know what this
will be when it executes, making it hard to read the function at a glance.
arrow functions do not have their own this, if you use call([this obj], args)
, apply([this obj], args)
, Any "this" argument is ignored. I guess the same applies to bind(obj)
, it doesn't bind this to the object you provided because it doesn't have its own this.
this
inside arrow functions is decided by this
in the lexical scope where the arrow function is defined. If you define your handleInputChange
in global scope, this
inside is the global object(in browser it's window), that's the reason you get the error.
If you want to use bind
, you can define the function like this
function handleInputChange(key, value) { this.setState(key: value) }
When you call bind
, this
will be set to the object you provided in bind
.
Since you are calling this function inside the class, it's better to define it as a method within the class instead of defining it outside, so that the this
issue is less of a, well, issue.
Inside the class makes it fairly straightforward:
constructor(props) {
this.handleInputChange = this.handleInputChange.bind(this)
}
handleInputChange() {
//Code
}
Or if you want to avoid having to do the messy bind
method, you can use an arrow function for the method:
handleInputChange = () => {
console.log('This is: ', this);
}
...
render() {
return(
<button onClick={this.handleInputChange}>Click</button>
);
}
Reference react handling events
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.