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 ...
随机推荐
- 其它——Postman做接口测试
文章目录 一 介绍 二 下载安装 三 使用 四 批量接口测试(创建collections) 五 导出与导入同事的接口 5.1 导出 5.2 导入 一 介绍 在前后端分离开发时,后端工作人员完成系统接口 ...
- Django框架——forms组件、cookie与session
文章目录 1 forms 组件 1 校验字段功能 2 渲染标签功能 渲染方式1 渲染方式2 渲染方式3 3 渲染错误信息功能 视图 模板 4 组件的参数配置 5 局部钩子 6 全局钩子 2 cooki ...
- 单元测验4:人格知识大比武2mooc
单元测验4:人格知识大比武2 返回 本次得分为:10.00/10.00, 本次测试的提交时间为:2020-09-06, 如果你认为本次测试成绩不理想,你可以选择 再做一次 . 1 单选(2分) 关于M ...
- PHP-basename
basename 定义: basename() 函数返回路径中的文件名部分. 语法: basename(path,suffix) 参数 描述 path 必需.规定要检查的路径 suffix 可选.规定 ...
- DP 复习
背包 约定使用 \(v_i\) 表示放入第 \(i\) 件物品的花费,\(w_i\) 表示第 \(i\) 件物品的价值,背包容量 \(M\),物品件数 \(N\). 01 背包 每种物品仅有一件,可以 ...
- 新手面对安卓6.0以上的版本时出现一个关于文件权限检测的问题,报错为:“无法解析符号 'checkSelfPermission'”,解决办法
[[注意]:这只是笔者在遇到这个问题时的解决方法,如果对您毫无帮助,请自寻他法!!!] 面对新手:在简单做一个音乐播放程序时,如果面对安卓6.0以上的版本,就会出现一个关于文件权限检测的问题,报错为: ...
- 洛谷P3392 涂国旗(暴力枚举)
# 涂国旗 ## 题目描述 某国法律规定,只要一个由 $N \times M$ 个小方块组成的旗帜符合如下规则,就是合法的国旗.(毛熊:阿嚏--) - 从最上方若干行(至少一行)的格子全部是白色的: ...
- kubernetes驱逐机制总结
概述 k8s的驱逐机制是指在某些场景下,如node节点notReady.node节点压力较大等,将pod从某个node节点驱逐掉,让pod的上层控制器重新创建出新的pod来重新调度到其他node节点. ...
- Semantic Kernel 将成为通向Assistants的门户
OpenAI 也推出了让开发者更容易使用 OpenAI API 的开发方式--Assistants API.Sam Altman 表示,市面上基于 API 构建 agent 的体验很棒.比如,Shop ...
- 文心一言 VS 讯飞星火 VS chatgpt (130)-- 算法导论11.2 2题
二.用go语言,对于一个用链接法解决冲突的散列表,说明将关键字 5,28,19,15,20,33,12,17,10 插入到该表中的过程.设该表中有 9 个槽位,并设其散列函数为 h(k)=k mod ...