要求:通过点击事件 得到state中定义的变量的值
1.定义state
import React, { Component } from 'react'
export default class App extends Component {
// 直接使用赋值语句
state = {
count: 0,
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
</div>
)
}
}
2.绑定点击事件
误区:直接绑定
报错: Cannot read properties of undefined (reading 'state')
使用如下的代码
class App extends Component {
state = {
count: 0,
}
handleClick() {
//报错: Cannot read properties of undefined (reading 'state')
console.log(this.state.count)
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
<button onClick={this.handleClick}>+1</button>
</div>
)
}
}
原因:
render函数是被组件实例调用的,其中的this指向的就是当前的组件实例,但是如果赋值给点击事件了,this则改变了指向,由React内部直接调用onClick,此时的this则是undefined (class内部开启局部的严格模式this不指向window)
3.修改this指向:
方式一:
高阶函数(函数作为参数传递的函数):通过 this 来直接调用 函数 并返回箭头函数
[也称:函数柯里化:通过函数调用继续返回函数的形式,实现多次接收参数最后统一处理的函数编码形式 ]
class App extends React.Component {
state = {
count: 0,
}
handleClick() {
// 这里的 this 指向是什么?那就看是谁调用的!
return () => {
console.log(this.state.count)
}
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
<button onClick={this.handleClick()}>+1</button>
</div>
)
}
}
方式二:
包裹一层箭头函数
箭头函数中的 this 指向“外部”,即 render 函数,而 render 函数中的 this 正是组件实例
class App extends Component {
state = {
count: 0,
}
handleClick() {
console.log(this.state.count)
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
<button onClick={() => this.handleClick()}>+1</button>
</div>
)
}
}
方式三:
使用 bind,改变this指向
class App extends Component {
state = {
count: 0,
}
handleClick() {
console.log(this.state.count)
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
{/* bind 谁,handleClick 中的 this 就是谁
bind 的返回值是一个新函数,这个新函数和 handleClick 函数公用一个函数体
*/}
<button onClick={this.handleClick.bind(this)}>+1</button>
</div>
)
}
}
方式四:
通过赋值语句往实例上面添加一个箭头函数
class App extends Component {
state = {
count: 0,
}
//“外层” this 是组件实例
handleClick = () => {
console.log(this.state.count)
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
<button onClick={this.handleClick}>+1</button>
</div>
)
}
}
方式五:
在构造函数中再创建一个实例方法,和原型方法公用一个函数体
class App extends React.Component {
constructor() {
super()
this.state = {
count: 0,
}
// 1. 往实例自身上又挂载了一个 handleClick2 函数
// 2. 此函数的函数体是通过原型上 handleClick 函数生成的新函数
// 3. 并把原型上 handleClick 函数中的 this 通过 bind 绑定为了 this,而这里构造函数中的 this 正是实例对象
// 4. 其实点击的时候调用的是这个构造函数 handleClick2(就近原则),而这个构造函数中的 handleClick2 执行的是原型上的 handleClick 的函数体
this.handleClick2 = this.handleClick.bind(this)
}
//原型上的函数体
handleClick() {
console.log(this.state.count)
}
render() {
return (
<div>
<h2>计数器:{this.state.count}</h2>
<button onClick={this.handleClick2}>+1</button>
</div>
)
}
}