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 ...
随机推荐
- AtCoder Grand Contest 038题解
好久没更了 写点东西吧= = A 01Matrix 简单构造 左上角和右下角染成1其他染成0即可 #include<bits/stdc++.h> #define ll long long ...
- matlab-线性回归
1.调用函数regress(Y,X,alpha),plpha是置信度,如果直接用regress(Y,X)则默认置信度为0.05,Y是一个 的列向量,X是一个 的矩阵,其中第一列是全1向量. 2.函数返 ...
- c3p0参数
<c3p0-config> <default-config> <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数.Default: 3 --> < ...
- Anaconda3(4)安装pytorch
安装链接 https://pytorch.org/ 0在anaconda3安装python3.6环境 https://blog.csdn.net/u012005313/article/details ...
- 从rpm包提取rpm spec 的几种方法
包含了源码包 先安装,然后在rpmbuild 目录直接可以查看文件 不用安装 ,使用rpm2cpio rpm2cpio myrpm.src.rpm | cpio -civ '*.spec' 没有源码 ...
- 题解 洛谷 P2010 【回文日期】
By:Soroak 洛谷博客 知识点:模拟+暴力枚举 思路:题目中有提到闰年然后很多人就认为,闰年是需要判断的其实,含有2月29号的回文串,前四位是一个闰年那么我们就可以直接进行暴力枚举 一些小细节: ...
- NOIp初赛题目整理
NOIp初赛题目整理 这个 blog 用来整理扶苏准备第一轮 csp 时所做的与 csp 没 有 关 系 的历年 noip-J/S 初赛题目,记录了一些我从不知道的细碎知识点,还有一些憨憨题目,不定期 ...
- idea 2018.1 创建springboot开启找回Run Dashboard
Run Dashboard 他是一个代替Run窗口的一个更好清晰简介的一个启动器.一般我们需要启动多个窗口时,Run窗口不能让我们直观的看到我们看到每一个端口的变化. 我们可以对比一下这个是Run D ...
- haproxy 配置文件详解 之 defaults
配置示例: defaults mode http retries timeout connect 10s timeout client 20s timeout server 30s timeout c ...
- org.Hs.eg.db
bioconduction 主页 http://www.bioconductor.org/packages/release/data/annotation/html/org.Hs.eg.db.html ...