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 ...
随机推荐
- MapReduce 程序mysql JDBC驱动类找不到原因及学习hadoop写入数据到Mysql数据库的方法
报错 :ClassNotFoundException: com.mysql.jdbc.Driver 需求描述: hadoop需要动态加载个三方jar包(比如mysql JDBC 驱动包),是在MR结束 ...
- sqlyog 下载
https://www.cnblogs.com/givemelove/p/7777975.html
- SDOI2010选做
Round1 D1T1外星千足虫 \(BSOJ2793\)--高斯消元解异或方程组 简述 有\(n\)个数\(\{a_i\}\) 给出\(m\)个信息,每个信息给出\(\displaystyle{(\ ...
- Oracle EBS 11i x86-64 的预安装
1.EBS11i的软件组成,28个zip包 Oracle ApplicationsOracle Application with NLSOracle Database technology stack ...
- 操作excel文件爬取nvd.nist数据
#!/usr/bin/env python # encoding: utf-8 #@author: jack import random from time import sleep import p ...
- linux网络编程之用socket实现简单客户端和服务端的通信(基于UDP)
单客户端和服务端的通信(基于UDP) 代码 服务端代码socket3.c #include<sys/types.h> #include<sys/socket.h> #inc ...
- Scala反射(二)
我们知道,scala编译器会将scala代码编译成JVM字节码,编译过程中会擦除scala特有的一些类型信息,在scala-2.10以前,只能在scala中利用java的反射机制,但是通过java反射 ...
- Python爬虫爬取BT之家找电影资源
一.写在前面 最近看新闻说圣城家园(SCG)倒了,之前BT天堂倒了,暴风影音也不行了,可以说看个电影越来越费力,国内大厂如企鹅和爱奇艺最近也出现一些幺蛾子,虽然目前版权意识虽然越来越强,但是很多资源在 ...
- WebBrowser内存泄露
使用WebBrowser控件开发的程序,占用内存会随着时间不停增长,最终内存溢出导致崩溃.究其原因是由于其自身的缺陷造成的.每一次加载新页面,WebBrowser就会多占用10-20M内存,有资料说是 ...
- 【2019年05月20日】A股滚动市盈率PE历史新低排名
2010年01月01日 到 2019年05月20日 之间,滚动市盈率历史新低排名. 上市三年以上的公司, 2019年05月20日市盈率在300以下的公司. 1 - 阳光照明(SH600261) - 历 ...