前言,起因在于今日同事问起,发现不能很好的解释这个问题,所以自己下来重新屡了一下思路,记录一下。
一、什么是箭头函数,以及为什么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里的使用的原因,以上就是我自己的看法,如果哪里说的不对,请大家指出来,共同进步。最近无时无刻不在感觉自己知识的不牢固。还是要踏实学习,勤思考才行..