解释React为什么onClick函数绑定都用箭头函数()=>{}

前言,起因在于今日同事问起,发现不能很好的解释这个问题,所以自己下来重新屡了一下思路,记录一下。

一、什么是箭头函数,以及为什么React里要用箭头函数

1. 下面这两个函数相同。只是react组件化,不支持在组建内部写function,所以现在用箭头函数代替js里的写法

// 传参写法
// 原生js写法
function test(params) {
    
    console.log('this = ',this)
}

<div onClick={test(123)}></div>

//等价于下面react写法


test2 = param => () => {
    console.log('param = ',param)
}

<div onClick={this.test2(123)}></div>

//不传参写法
function test(){}   <=>   test = () => {}

2. 你肯定会继续问,那如果只是替换原来的function写法, 直接在react里写

<div onClick={test(123)}></div>

为什么要变成 this.test(123) 呢? 

这是因为 在使用ES6 classes或者纯函数时,React不会自动绑定this到当前组件上,需要手动实现this的绑定。

如果在React里继续 test(123),此时test的对象指向的是window,而不是改组建内部,所以会是undefined,这个时候,编译器检测到你onClick 绑定了一个 undefined, 所以会报错

以上,按照我的思路,首先,你要了解箭头函数其实是等价替换原有js的函数写法,其次,比原有写法多写this是因为react不会自动绑定this到当前组建。

二、你还有疑惑吗

如果我们一开始不知道箭头函数等价替换了function函数,我们就很容易在React里把函数写成下面这个样子

test(param){
    console.log(param);
}

<div onClick={this.test(123)}></div>

期望的效果是,点击一次这个div,就打印一次传入的参数123,但是,你发现,只在页面开始渲染的时候打印了函数,而点击的时候没有反应。 这是为什么呢?

一开始会打印,是因为页面在渲染的时候,把this.test()当成一个函数预执行,所以一开始打印123,而这个函数返回的是undefined。所以你点击的时候,不会有输出。此时你的 onClick = undefined;

那如果我是变态一点,给这个函数加返回值

test(param){
    console.log(param);
    return param
}

<div onClick={this.test(123)}></div>

会发生什么呢? 答案是:会报错。因为这个时候 onClick = 123; 不是一个函数,所以报错。

三、ES6为什么要引入箭头函数呢?

   这里直接用一下廖雪峰老师的例子。

接上,如果没有箭头函数,我们需要用hack的写法去解决this作用域的问题。

var obj = {
    birth: 1990,
    getAge: function () {
        let that = this;
        var b = this.birth; // 1990
        var fn = function () {
            return new Date().getFullYear() - that.birth; // 此时that指向当前作用域
        };
        return fn();
    }
};

obj.getAge() // 输出 29  上面输出25是因为廖老师写这篇文章的时候是15年,现在19年啦

四、React里为什么要bind一下呢?

理由同上面 (一.2) 里提过的,react不会自动绑定函数。比如你可能会这样写

test(){
    console.log('123');
}

<div onClick={this.test}></div>

你发现每次点击,确实会打印123,但是你并没有按照箭头函数的形式写,你可能会觉得,这样也能用,但是,如果你试着打印一下。


constructor(props) {
  super(props);
  this.state = {
    visible: true,
  }
}
test(){
   console.log(this.state.visible);
}

你会发现打印的是undefined。这就是因为不用箭头函数,组件里的函数不会自动绑定this,这个时候,你需要在constructor里绑定this。

constructor(props) {
  super(props);
  this.state = {
    visible: true,
  }
  this.test = this.test.bind(this);
}
test(){
   console.log(this.state.visible);
}

这样每次点击,就可以打印出来visible的值了。但这种写法有一种缺陷,就是不能传参(可能是我目前没了解到这种写法传参的方法)

补一个关于函数和方法的定义

  函数(function): 函数是带有名称(named)和参数的JavaScript代码段,可以一次定义多次调用。

  方法(method): 当将函数和对象合写在一起时,函数就变成了 "方法"(method)// 当函数赋值给对象的属性,我们称为"方法"

  也就是函数和方法本质上是一样的,只不过方法是函数的特例,是将函数赋值给了对象。

 

完结。关于箭头函数和React里的使用的原因,以上就是我自己的看法,如果哪里说的不对,请大家指出来,共同进步。最近无时无刻不在感觉自己知识的不牢固。还是要踏实学习,勤思考才行..

 

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值