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 ...
随机推荐
- VS Code配置Python
安装 1.安装python插件 直接在VS Code里搜索“Python”插件,安装. 2.下载Python 去官网下载Python 其他的插件在第一次运行Python程序会提示,按要求安装即可. 运 ...
- 配置Maven环境变量-Eclipse/Idea添加Maven
1. 文件下载 官网下载地址:http://maven.apache.org/download.cgi 下方有我提供的下载链接. 由于下载缓慢,提供一份我的下载链接:https://www.lanzo ...
- hadoop java.io.EOFException: Unexpected end of input stream
执行hadoop 报错 java.io.EOFException: Unexpected end of input stream at org.apache.hadoop.io.compress.De ...
- ES6异步操作Promise
什么是Promise Promise是异步编程的一种解决方案,说白了就是一个构造函数,带有all,reject,resolve这几个方法,圆形上有then,catch等方法 Promise的特点 对象 ...
- B 题解————2019.10.16
相信他说的话,但不要当真 [题目描述]有一个长度为 n 的自然数序列 a,要求将这个序列恰好分成至少 m 个连续子段. 每个子段的价值为该子段的所有数的按位异或.要使所有子段的价值按位与的结果最大,输 ...
- 从零和使用mxnet实现softmax分类
1.softmax从零实现 from mxnet.gluon import data as gdata from sklearn import datasets from mxnet import n ...
- Kafka Rebalance机制分析
什么是 Rebalance Rebalance 本质上是一种协议,规定了一个 Consumer Group 下的所有 consumer 如何达成一致,来分配订阅 Topic 的每个分区. 例如:某 G ...
- python基础_格式化输出(%用法和format用法)(转载)
python基础_格式化输出(%用法和format用法) 目录 %用法 format用法 %用法 1.整数的输出 %o -- oct 八进制%d -- dec 十进制%x -- hex 十六进制 &g ...
- mac下操作小记
安装homebrew https://juejin.im/post/5c738bacf265da2deb6aaf97 主要问题:按官网安装方法(/usr/bin/ruby -e "$(cur ...
- centos7 中iptables、firewalld 和 netfilter 的关系
centos7系统使用firewalld服务替代了iptables服务,但是依然可以使用iptables来管理内核的netfilter 但其实iptables服务和firewalld服务都不是真正的防 ...