react的事件处理为什么要bind this 改变this的指向?
react的事件处理会丢失this,所以需要绑定,为什么会丢失this?
首先来看摘自官方的一句话:
You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default.
这句话大概意思就是,你要小心jax回调函数里面的this,class方法默认是不会绑定它的
让我十分疑惑,在我的知识范围理解中,class是es6里面新增的方法,不就用来继承原有对象上的属性和方法创建新的对象吗?就是代替原来的构造函数的一种更清晰的方式,为什么就不会绑定this呢?
可是查阅了一些es6的文档,并不是这样的啊,和class方法没啥关系吧,为什么要它背锅呢?
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true}; // This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
} handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
} render() {
return (
<button onClick={this.handleClick}> //这里调用的this也能拿到啊??
{this.state.isToggleOn ? 'ON' : 'OFF'} //这里的this为什么没问题?
</button>
);
}
}
这是官网上的一段代码,如果是是因为class的关系,handleClick里面拿不到this,那为什么render里面能拿到this,所以和class根本没关系吧本来就能拿到,那问题出现在哪里,为什么拿不到?
先看看解决办法
第一种,在constructor里面用bind绑定this
constructor(props) {
super(props);
this.state = {isToggleOn: true}; // This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
第二种,声明方法的时候使用箭头函数
handleClick = () => {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
第三种,调用的时候使用箭头函数
render() {
return (
<button onClick={ () => { this.handleClick } }>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
这个时候我想起了原生dom绑定click的方法
<button onclick ="handleClick()">点我</button>
两者比较,我发现了个区别,原生的绑定方法事件名后面多了个()
于是我尝试着在react里面的事件加一个()
render() {
return (
<button onClick={ this.handleClick() }>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
class App extends Component {
handleClick(){
console.log(this); //下面调用加了(),这个时候发现,this是可以拿到的
}
render() {
return (
<div className="App">
<button onClick={this.handleClick()}>点我</button> //这里加了括号的
</div>
);
}
}
好像问题越来越明朗了,为啥会拿不到,和class没有关系,完全是因为react自己封装的东西,先会把{}里面的代码解析一遍,于是大概就是下面这种情况了
const obj = {
num:1
}
obj.handleClick = function () {
console.log(this);
}
console.log(eval(obj.handleClick )); // f(){ console.log(this) } react对{}的解析
(eval(obj.handleClick))() //onclick触发点击事件 这里输出this是window,所以就等于丢失了this指向 console.log(eval(() => { obj.handleClick() })); // () => { obj.handleClick() } react对{}的解析
(eval(() => {obj.handleClick()}))() //onclick触发点击事件 这里输出this还是obj,所以this就保留了
所以问题出在react对{}的解析会把this的指向解除了
react的事件处理为什么要bind this 改变this的指向?的更多相关文章
- React中的事件处理为什么要bind this?
个人总结: 问: 请给我讲一下React中的事件处理为什么要bind this? 答: 好的,比如说我写了一个类组件,有个onClick属性 ,onClick={ this.fun },如果不bind ...
- bind改变this的指向
<script type="text/javascript"> var Hello = function(){ this.setT = function(){ wind ...
- this指向详解及改变它的指向的方法
一.this指向详解(彻底理解js中this的指向,不必硬背) 首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是 ...
- 改变this的指向问题;
用call()和apply()改变this的指向,那什么时候用this呢?(构造函数),那为什么要用构造函数呢?(为了生成对象). 1.解决函数内this指向的问题 (1)var that/_this ...
- JavaScript中this的用法 及 如何改变this的指向
要懂得JavaScript中this的用法,首先需要知道,JavaScript中的作用域相关知识. var fun = function(){ var flag = 1; console.log(fl ...
- 有关call和apply、bind的区别及this指向问题
call和apply都是解决this指向问题的方法,唯一的区别是apply传入的参数除了其指定的this对象之外的参数是一个数组,数组中的值会作为参数按照顺序传入到this指定的对象中. bind是解 ...
- 3种方法改变this的指向
<body> <div style="width: 200px;height: 200px;hotpink;"></div> & ...
- React事件处理函数的bind复用和name复用
一.bind复用 <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset=&qu ...
- react篇章-事件处理
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...
随机推荐
- Spring Boot 各版本的Java版本要求
Spring Boot 各版本的Java版本要求 Spring Boot 与 Java 对应版本,以下表格由官方网站总结. 官网:https://spring.io/projects/spring-b ...
- python语言(八)多线程、多进程、虚拟环境、unittest、生成测试报告
一.多线程 进程与线程 进程:进程是资源(CPU.内存等)分配的最小单位,进程有独立的地址空间与系统资源,一个进程可以包含一个或多个线程 线程:线程是CPU调度的最小单位,是进程的一个执行流,线程依赖 ...
- 转:ubuntu16安装python3.6并将环境设置为系统默认
按照本文升级到3.6,但pip无法运行了,问题没有解决 1.添加python3.6安装包,并且安装 sudo apt-get install software-properties-common su ...
- WebForm 打开默认页
原文:https://www.cnblogs.com/lionden/p/3728716.html <configuration> <system.webServer> < ...
- CF 494E Sharti
CF 494E Sharti 题意:一个\(n \times n\)的棋盘,共有m个矩形中的格子为白色.两个人需要博弈,每次操作选择一个边长不超过k的正方形并翻转颜色,每次翻转需要正方形的右下角为白色 ...
- mysql(二)事务 & 事务的实现 & 锁
参考文档: mvcc:https://www.cnblogs.com/chenpingzhao/p/5065316.html 事务的实现:https://www.linuxidc.com/Linux/ ...
- [Gamma]Scrum Meeting#5
github 本次会议项目由PM召开,时间为5月30日晚上10点30分 时长15分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写博客,组织例会 撰写博客,组织例会 swoip 前端显示屏幕,翻译 ...
- shell脚本监控k8s集群job状态,若出现error通过触发阿里云的进程监控报警
#!/bin/bash while [ 1 ] do job_error_no=`kubectl get pod -n weifeng |grep -i "job"|grep -c ...
- c# .net 使用Confluent.Kafka针对kafka进行生产和消费
首先说明一点,像Confluent.Kafka这种开源的组件,三天两头的更新.在搜索引擎搜索到的结果往往用不了,浪费时间.建议以后遇到类似的情况直接看官网给的Demo. 因为搜索引擎搜到的文章,作者基 ...
- 文本编辑 工具vim
一vim的3种常用模式:一般模式.编辑模式和命令模式 如果系统里没有vim工具,需安装 1,一般模式 首先复制一个文件到/tmp/目录下,并改名为1,txt 移动光标: h 或 向左箭头键(←) ...