The profile
When using React for the first time, this is often lost. Here are a few ways to bind this to React.
First look at the following code:
class Demo extends Component{
constructor(props){
super(props)
}
handleClick(){
console.log('this'.this)}render(){
return (
<div>
<button onClick={this.handleClick}>Am I</button>
</div>
)
}
}
ReactDOM.render(<Demo/>.document.getElementById('test'))
Copy the code
It would have been easy to write like this if we had been developing in Vue, but in React we would have lost the reference to this when we executed it. The first thing we need to understand is that the handleClick and render methods we define in the class are defined in the class prototype. Only the instance object of the class can be called, and the this inside the function refers to the instance itself. When reactdom.render () is executed, it helps us create an instance object and calls the render method, so this inside the render method points to the instance itself. this is a reference to the this.handleClick method. But when we click, handleClick’s execution context is Window, since JSX is compiled by Babel to enable strict mode. So this pointer becomes undefined.
1. Use bind in the constructor to redirect this
class Demo extends Component{
constructor(props){
super(props)
// This method is defined on the instance object.
this.handleClick = this.handleClick.bind(this)}handleClick(){
console.log('this'.this)}render(){
return (
<div>
<button onClick={this.handleClick}>Am I</button>
</div>
)
}
}
ReactDOM.render(<Demo/>.document.getElementById('test'))
Copy the code
This approach is where we add a method for each instance in Constructor and bind this to itself. The onClick bound handler is no longer a function on the instance prototype chain, but a method added to the instance itself from constructor.
Let’s look at the following code
class Demo extends Component{
handleClick(){
console.log('this'.this)}render(){
return (
<div>
<button onClick={this.handleClick(e)}>Am I</button>
</div>
)
}
}
ReactDOM.render(<Demo/>.document.getElementById('test'))
Copy the code
If we need to pass parameters, we might find that the event did not bind successfully. If we look closely, we will see that we are binding the return value of the handleClick method undefined to the onClick handler. (Unlike Vue’s template parsing, this is done in JS syntax) we can use the following scheme.
2. Bind events using arrow functions
class Demo extends Component{
handleClick(){
console.log('this'.this)}render(){
return (
<div>
<button onClick={(e)= >Enclosing handleClick (e)} > me</button>
</div>
)
}
}
ReactDOM.render(<Demo/>.document.getElementById('test'))
Copy the code
We know that the “this” of the render function refers to the instance itself, so we can use the arrow function directly during binding, and the execution context of handleClick is the scope defined by the arrow function.
3. Define instance methods using arrow functions
class Demo extends Component{
// This method is defined in the instance object, and the execution context is the instance itself
handleClick = () = >{
console.log('this'.this)}render(){
return (
<div>
<button onClick={this.handleClick}>Am I</button>
</div>
)
}
}
ReactDOM.render(<Demo/>.document.getElementById('test'))
Copy the code
The solution is to define the method directly on itself and point this to the instance itself via the arrow function.