解决react中this指向的问题

本文介绍了在React中处理事件的四种方法:直接使用this,包裹箭头函数,使用bind,以及定义实例方法。讨论了class中的实例方法与原型方法的区别,并提供了相关代码示例。此外,还解释了如何确保this指向正确,以正确访问组件状态。
摘要由CSDN通过智能技术生成

方法一

高阶函数:通过 this 来直接调用 handleClick 并返回箭头函数。

代码如下:

export default class App extends Component {
	state = {
		count: 0
	}
	handelClick() {
		// this指向实例对象
		// console.log(this.state.count)
		return () => {
			// 箭头函数没有自己的this,会向外部找, this指向外部,也指向实例对象
			console.log(this.state.count)
		}
	}
	render() {
		return (
			<div style={{ textAlign: 'center' }}>
				<h2>计数器:{this.state.count}</h2>
				<button onClick={this.handelClick()}>+1</button>
			</div>
		)
	}
}

 

 方法二

包裹一层箭头函数。箭头函数中的 this 指向“外部”,即 render 函数,而 render 函数中的 this 正是组件实例。

export default class App extends Component {
	state = {
		count: 0
	}
	handelClick() {
		//
		console.log(this.state.count)
	}
	render() {
		return (
			<div style={{ textAlign: 'center' }}>
				<h2>计数器:{this.state.count}</h2>
				{/* 外面包一层箭头函数 */}
				<button
					onClick={() => {
						this.handelClick()
					}}
				>
					+1
				</button>
			</div>
		)
	}
}

方法三

使用 bind。

export default class App extends Component {
	state = {
		count: 0
	}
	handelClick() {
		//
		console.log(this.state.count)
	}
	render() {
		return (
			<div style={{ textAlign: 'center' }}>
				<h2>计数器:{this.state.count}</h2>
				{/* 外面包一层箭头函数 */}
				<button onClick={this.handelClick.bind(this)}>+1</button>
			</div>
		)
	}
}

#扩展

关于 class 中的实例方法和原型方法?

原型方法演示

class App {
    handleClick() {}
}

const app1 = new App()
const app2 = new App()
// 通过打印也能发现 handleClick 确实是挂载到原型上的
console.log(app1)
// 每一个实例访问到的都是挂载到原型上的方法,所以等价
console.log(app1.handleClick === app2.handleClick)

实例方法演示

class App {
    handleClick = () => {}
}

const app1 = new App()
const app2 = new App()
// 通过打印也能发现 handleClick 确实是挂载到实例上的
console.log(app1)
// 每一个实例访问到的都是挂载到自己上的方法,所以不等价
console.log(app1.handleClick === app2.handleClick)

所以,要明白在 class 中直接写的方法和通过赋值语句添加的方法本质上不一样。

注意:在 constructor 中挂载的方法也是实例方法。

方法四

通过赋值语句往实例上面添加一个箭头函数。

export default class App extends Component {
	state = {
		count: 0
	}

	handelClick = (e) => {
		// 实例方法
		console.log(this.state.count)
	}
	render() {
		return (
			<div style={{ textAlign: 'center' }}>
				<h2>计数器:{this.state.count}</h2>
				<button onClick={this.handelClick}>+1</button>
			</div>
		)
	}
}

证明“外层” this 确实是组件实例  

class App {
    temp = this
}

const app = new App()
console.log(app === app.temp)

方法五

在构造函数中再创建一个实例方法,和原型方法公用一个函数体。

export default class App extends Component {
  constructor() {
    super()
		this.state = {
			count: 0
		}
		// 重新创建实例方法 改变函数的方法生成新方法赋值给创建的方法
		this.handelClick = this.handelClick.bind(this)
	}

	handelClick(e) {
		// 实例方法
		console.log(this.state.count)
	}
	render() {
		return (
			<div style={{ textAlign: 'center' }}>
				<h2>计数器:{this.state.count}</h2>
				<button onClick={this.handelClick}>+1</button>
			</div>
		)
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值