react 事件函数中 this 绑定问题
在使用类方式创建组件时,类中定义一个函数,并且绑定到元素的点击事件上,此时这个函数中this指向并不是当前这个组件。
组件代码如下:
class App extends React.Component {
// 组件数据
constructor() {
super()
this.state = {
message: 'hello world',
}
}
// 点击函数
btnClick() {
this.setState({
message: 'hello react',
})
}
// 渲染函数
render() {
return (
<div>
<h2>{this.state.message}</h2>
<button onClick={this.btnClick}>
修改文本
</button>
</div>
)
}
}
如上代码中,点击修改文本按钮,会发生如下报错
Uncaught TypeError: Cannot read properties of undefined (reading 'setState')
提示 undefined 找不到 setState 方法。
主要原因如下:
- 默认情况下
btnClick内的this是绑定的是undefined,熟悉this绑定的应该知道,this是绑定运行时调用这个函数的对象,this绑定详解可以查看:https://www.cnblogs.com/easy1996/p/17954257; - 在正常的DOM操作中,监听点击,调用监听函数的其实是节点对象,比如上面的按钮对象;
- 在React中,并不是直接渲染真实的DOM,render渲染函数中所编写的button只是一个语法糖,最终会编译成
React.createElement("button", {onClick: this.btnClick}); - 同时会将
btnClick函数暴露出来,以const click = onClick(伪代码)的形式; - 当点击事件触发时,react执行上面的
click函数,默认里面this就是绑定的undefined,相当于window中调用函数(严格模式下为undefined);
解决方法:
知道了问题在于 this 的绑定不对,有三种方式解决:
1.给点击函数显式绑定 this
class App extends React.Component {
constructor() {
super()
this.state = {
message: 'hello world',
}
// 位置1.在此处重新给点击函数绑定this为组件对象
this.btnClick = this.btnClick.bind(this)
}
btnClick() {
this.setState({
message: 'hello react',
})
}
render() {
return (
<div>
<h2>{this.state.message}</h2>
{/* 位置2.直接在渲染函数中重新绑定this */}
<button onClick={this.btnClick.bind(this)}>
修改文本
</button>
</div>
)
}
}
在上面两个位置任选一个重新绑定 this 为组件对象即可。
2.使用 ES6 class field
class App extends React.Component {
constructor() {
super()
this.state = {
message: 'hello world',
}
}
// class field
btnClick = () => {
this.setState({
message: 'hello react',
})
}
render() {
return (
<div>
<h2>{this.state.message}</h2>
<button onClick={this.btnClick}>修改文本</button>
</div>
)
}
}
上面使用 class field的方式,给 btnClick 赋值一个箭头函数,箭头函数默认绑定当前环境的 this。
3.直接在按钮上使用箭头函数(推荐)
class App extends React.Component {
constructor() {
super()
this.state = {
message: 'hello world',
}
}
btnClick() {
this.setState({
message: 'hello react',
})
}
render() {
return (
<div>
<h2>{this.state.message}</h2>
{/* 直接绑定箭头函数 */}
<button onClick={() => this.btnClick()}>修改文本</button>
</div>
)
}
}
再看一下此时执行的流程:
onClick绑定的是一个箭头函数,箭头函数的this绑定的是App组件对象;- 前面的两个例子中是将这个函数引用赋值给
onClick,等待按钮事件点击,然后再触发这个引用的函数,onClick={this.btnClick}; - 而上面的代码中,是
onClick={() => this.btnClick()},是将() => this.btnClick()这个箭头函数赋值给onClick,按钮点击触发这个箭头函数,而箭头函数内部是一个已经调用过的btnClick()函数,包含(),调用时在箭头函数内部,所有this绑定的是App组件对象。
react 事件函数中 this 绑定问题的更多相关文章
- react事件处理函数中绑定this的bind()函数
问题引入 import React, { Component } from 'react'; import { Text, View } from 'react-native'; export def ...
- React之函数中的this指向
我们都知道在React中使用函数时,有两种写法,一是回调函数,二是直接调用,但需要在构造函数中绑定this,只有这样,函数中的this才指向本组件 总结一下没有绑定this的函数中的this指向 不管 ...
- js事件函数中(ev)是什么鬼?
首先,从ev所在的位置就可以得知,ev是参数. 在ev中包含了事件触发时的函数, 比如: click事件的ev中包含着e.pageX,e.pageY keydown事件中包含着ev.keyCode等 ...
- React事件函数简介
一.事件汇总 二.例子 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset= ...
- js事件函数中function(e){}
简单来说就是指向了当前发生的事件(click.mouseover等等),保存了当前事件的信息.如鼠标点击事件,有鼠标的坐标信息.其中,e是标准浏览器传递进去的事件参数,低版本IE不会传递,事件参数放置 ...
- js 事件函数中的参数带换行符或换行标签都不能起作用的解决方法
把问题参数值赋给标签的属性data-value,通过属性值获取参数值.
- jquery事件函数和原生事件绑定函数中return false的区别
一直听说jquery中事件函数返回false,相当于调用了event.preventDefault()和event.stopPropagation()两个方法,今天就想看看dom中0级.1级.2级事件 ...
- React应该如何优雅的绑定事件?
前言 由于JS的灵活性,我们在React中其实有很多种绑定事件的方式,然而,其实有许多我们常见的事件绑定,其实并不是高效的.所以本文想给大家介绍一下React绑定事件的正确姿势. 常见两种种错误绑定事 ...
- Unity3D中事件函数的运行顺序
Unity3D中脚本的生命周期是依照预先定义好的事件函数的运行流程来演化的,详细流程例如以下: Editor模式下Reset: 当脚本第一次被挂到GameObject上或用户点击Resetbutton ...
- react事件机制
1. react的事件是合成事件((Synethic event),不是原生事件 <button onClick={this.handleClick}></button> &l ...
随机推荐
- C++的extern关键字在HotSpot VM中的重要应用
extern关键字有两个用处: (1)extern在C/C++语言中表示函数和全局变量作用范围(可见性)的关键字,这个关键字会告诉编译器,其声明的函数和变量可以在本模块或其它模块中使用. (2)在C+ ...
- jquery设置图片可手动拖拽
JQuery是一款流行的JavaScript框架,可以轻松实现网页交互效果.而其中一种常见效果是图片手动拖拽.以下是设置图片手动拖拽的JQuery代码. 1 2 3 4 5 6 7 8 9 10 11 ...
- MySQL系列之优化——1.优化哲学、2. 优化工具的使用、3. 优化思路分解、4. MySQL参数优化测试、5.1 参数优化、6. 参数优化结果、7. 锁的监控及处理、8. 主从优化
文章目录 1.优化哲学 1.1 为什么优化? 1.2 优化风险 1.3 谁参与优化 1.4 优化方向 1.5 优化的范围及思路 优化效果和成本的评估: 2. 优化工具的使用 2.1 系统层面的 2.1 ...
- CF1368B
题目简化和分析: 因为要求长度最小,所以我们每个字符就应该发挥最大的价值,不会有没有作用的字符. 设有 \(x_1\) 个 \(c\) ,\(x_2\) 个 \(o\) ,\(x_3\) 个 \(d\ ...
- Go反射终极指南:从基础到高级全方位解析
在本文中,我们将全面深入地探讨Go语言的反射机制.从反射的基础概念.为什么需要反射,到如何在Go中实现反射,以及在高级编程场景如泛型编程和插件架构中的应用,本文为您提供一站式的学习指南. 关注[Tec ...
- 服务器常见问题排查(一)——cpu占用高、上下文频繁切换、频繁GC
一般而言cpu异常往往还是比较好定位的.原因包括业务逻辑问题(死循环).频繁gc以及上下文切换过多.而最常见的往往是业务逻辑(或者框架逻辑)导致的,可以使用jstack来分析对应的堆栈情况. 使用js ...
- CF1523D Love-Hate 题解
抽象化题意: 一共有 \(m\) 个元素,给定 \(n\) 个集合,每个集合的元素不超过 \(15\) 个,求出一个元素个数最多的集合 \(S\) 是至少 \(\lceil \dfrac{n}{2} ...
- off-line RL | CQL:魔改 Bellman error 更新,得到 Q 函数 lower-bound
论文题目: Conservative Q-Learning for Offline Reinforcement Learning CQL 是师兄盛赞的一篇论文:"是 off-line RL ...
- 2007年对Youtube小视频的分析文章
Understanding the Characteristics of Internet Short Video Sharing: YouTube as a Case Study 视频的种类 该研究 ...
- RT-Thread 中 minIni 组件包无法添加的解决方法
事件 今天在 Env 下添加 minIni 包的时候出现了无法将其添加到工程的情况.借此机会来记录一下如何解决该类问题. 如果你想快速排错可以直接到 [2.minIni 组件出现的问题]查看. 一.准 ...