为什么React类组件中clickHandler内部的this关键字值为undefined?
问题核心原因
你遇到的这个问题是类方法默认的this绑定规则和React事件回调的调用机制共同导致的,你之前记的规则没错:类方法的this默认确实指向实例,但这个规则的生效前提是你要按照类方法的常规方式调用它。
这里有两个需要明确的底层逻辑:
- ES6的class语法中,普通方法的this是「运行时绑定」而非「定义时绑定」。也就是说
clickHandler()里的this指向谁,完全由函数的调用方式决定,和它定义的位置没有直接关系。 - 你给
onClick传递的是this.clickHandler这个函数本身的引用,React触发点击事件调用该回调时,是直接将其作为普通函数执行的,没有绑定任何上下文。而React类组件默认运行在严格模式下,严格模式中普通函数直接调用时的this就是undefined。
你之前了解的「类函数内部的this指向实例」的场景,只有当你通过实例直接调用方法时才会生效,比如执行eventBindInstance.clickHandler()时,this会自动绑定到实例上。但你现在只是把函数地址传给了onClick,调用时没有前置的实例前缀,自然拿不到正确的this。
常见的四种解决方法
你可以根据场景任选一种使用,目前业界最推荐前两种方案:
- 构造函数内提前绑定this(类组件官方推荐旧写法)
在构造函数里把方法的this提前绑死到当前实例,后续调用就不会出现this丢失的问题:
constructor(props) { super(props); this.state = { message: "Hello", }; // 新增绑定逻辑 this.clickHandler = this.clickHandler.bind(this); }
绑定完成后直接在onClick中传this.clickHandler即可正常使用。
- 类属性箭头函数写法(最常用的简洁写法)
直接把clickHandler定义为箭头函数,箭头函数的this继承自定义时所在的上下文,不会随调用方式变化:
// 将原来的普通函数定义改为箭头函数 clickHandler = () => { this.setState({ message : 'Goodbye' }) console.log(this); }
这种写法不需要在构造函数中额外做绑定,代码更简洁,是目前大部分类组件项目的首选方案。
- 渲染时用bind绑定
直接在onClick属性位置绑定this:
<button onClick = {this.clickHandler.bind(this)}>Click</button>
该写法的缺点是每次组件render都会生成新的函数实例,可能引发不必要的子组件重渲染,性能损耗稍高,不推荐在频繁重渲染的组件中使用。
- 渲染时用箭头函数包裹
逻辑和第三种方案类似,用箭头函数把原有方法包一层,利用箭头函数的this继承特性拿到正确的实例:
<button onClick = {() => this.clickHandler()}>Click</button>
缺点和第三种方案一致,每次render都会生成新函数,仅适合简单Demo或者不会频繁重渲染的组件使用。
内容的提问来源于stack exchange,提问作者Prajwal
相关产品推荐
相关产品推荐

