深入理解React中何时使用箭头函数


Posted in Javascript onAugust 23, 2017

前言

相信大家当想起箭头函数时,脑海里可能会浮现 棒,酷,简洁,有趣 等形容词,其实,我们存在一些 更充分的理由 使我们在联想起 箭头函数 时不得不想到的,本文详细的给大家介绍了关于React何时使用箭头函数的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍:

解决 this 引起的问题

箭头函数不会在函数体内重新定义 this 的值,这使得在回调中的行为更容易预测,并且避免了 this 在回调中潜存的 bug

下面我们来看一个 example

我们期望点击按钮,改变按钮颜色,代码如下

class BrokenButton extends React.Component {
 render() {
 return (
  <button onClick={this.handleClick} style={this.state}>
  Set background to red
  </button>
 );
 }

 handleClick() {
 this.setState({ backgroundColor: "red" });
 }
}

render(<BrokenButton />, document.getElementById("root"));

然而,当我们点击按钮时,什么效果都没有,为什么会这样呢

其实,不是 handleClick 方法没有起作用,因为 JavaScript 中压根没有方法, JavaScript 中只有函数,而函数中的 this 存在一些规则,正是这些规则,让上面的 handleClick 中的 this 值变成了 null

你需要清楚明白的是: 你无法确定一个方法函数中 this 的指向,因为它的值跟函数的调用方式有关

除非,你使用 箭头函数,因为箭头函数中 this 的值是继承自 外围作用域

class Button extends React.Component {
 render() {
 return (
  <button
  onClick={() => this.setState({ backgroundColor: "red" })}
  style={this.state}
  >
  Set background to red
  </button>
 );
 }
}

render(<Button />, document.getElementById("root"));

现在就对了,接下来,我们继续

浏览器支持

浏览器对 箭头函数 的支持大概是 73%,因为目前,IE 并不支持。但如果你已经意识到这一点,并且你还会代码转译,这对你来说就不算什么问题

性能问题

大家都发现了,箭头函数 书写起来是非常容易的,但书写忒多的函数,也会造成一些问题

定义函数是昂贵的

浏览器每执行一次 =>,就需要创建一个 新的函数对象,这其实是一个比较 昂贵 的操作

当然,如果你不是想构建一个 性能超级无敌宇宙螺旋棒 的组件,渲染一个 非常长 的列表或 非常大 的表格,你也不会发现这是一个 问题

所以,如果你的组件只是在页面中渲染个几次,你也 没必要忒担心 性能这方面的问题

两个相同的箭头函数并不相等

为了让大家意识到这个问题,接下来,我们用 == 比较一下两个相同的箭头函数相不相等

const a = x => x,
  b = x => x;

render(
 <div>
 <h3>
  Are <code>a</code> and <code>b</code> equal by <code>==</code>?
 </h3>
 <p>
  {a == b ? "Yes!" : "No :("}
 </p>
 </div>,
 document.getElementById("root")
);

如果你在 render 中使用箭头函数,那么你在每次调用 render 时都会去创建一个新的函数对象,此时,即使使用 PureComponent 和 shouldComponentUpdate 也起不到优化作用

你可以在下面实例中看清这一点,其中, <PropChangeCounter /> 组件用于打印 props 改变的次数

import PropChangeCounter from "react-armory-prop-change-counter";

class App extends React.Component {
 constructor(props) {
 super(props);
 this.state = { email: "" };
 }
 render() {
 return (
  <div>
  <input
   placeholder="Email"
   value={this.state.email}
   onChange={e => this.setState({ email: e.target.value })}
  />
  <PropChangeCounter
   constant={"this doesn't change"}
   value={this.state.email}
   onChange={e => this.setState({ email: e.target.value })}
  />
  </div>
 );
 }
}

render(<App />, document.getElementById("root"));

只定义一次

如果你觉得 性能 对你的组件很重要,那么你肯定会想如果在组件中只定义箭头函数 一次 该有多好

其中一种实现方式是在 constructor 中使用箭头函数,当然,对于复杂些的组价来说,这会变的很笨拙

如果你使用了 Babel 或 create-react-app 构建你的应用,你可以将箭头函数设置为 class fields 或 arrow function methods

如下,你可以将 handleClick 重新定义为一个 arrow function method,来修复第一个 example 中的 bug

class Button extends React.Component {
 render() {
 return (
  <button onClick={this.handleClick} style={this.state}>
  Set background to red
  </button>
 );
 }

 // Note: this syntax is not yet part of JavaScript proper, but is slated
 // for inclusion in the next version. It should already work with Babel.
 handleClick = () => {
 this.setState({ backgroundColor: "red" });
 };
}

总结

  • 如果 环境支持 箭头函数,那么鼓励使用
  • 尽量避免对 React 组件 使用箭头函数,它会使 调试 变的困难
  • 如果有需要,可以在 render 中使用箭头函数
  • 为 性能 着想,避免在 render 中使用大量函数

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

原文链接:When should I use Arrow Functions? (James K Nelson)

Javascript 相关文章推荐
javascript+dom树型菜单类,希望朋友们一起进步
May 03 Javascript
javascript之bind使用介绍
Oct 09 Javascript
js加入收藏以及使用Jquery更改透明度
Jan 26 Javascript
javascript 获取函数形参个数
Jul 31 Javascript
JS实现灵巧的下拉导航效果代码
Aug 25 Javascript
Node.js 应用跑得更快 10 个技巧
Apr 03 Javascript
JavaScript核心语法总结(推荐)
Jun 02 Javascript
Javascript 实现简单计算器实例代码
Oct 23 Javascript
Jquery UI实现一次拖拽多个选中的元素操作
Dec 01 Javascript
vue-cli常用设置总结
Feb 24 Javascript
JavaScript页面倒计时功能完整示例
May 15 Javascript
基于JavaScript实现省市联动效果
Jun 22 Javascript
自定义类似于jQuery UI Selectable 的Vue指令v-selectable
Aug 23 #jQuery
JS数组交集、并集、差集的示例代码
Aug 23 #Javascript
关于Vue实现组件信息的缓存问题
Aug 23 #Javascript
详解webpack进阶之loader篇
Aug 23 #Javascript
Vue中定义全局变量与常量的各种方式详解
Aug 23 #Javascript
基于JavaScript实现带数据验证和复选框的表单提交
Aug 23 #Javascript
使用JS组件实现带ToolTip验证框的实例代码
Aug 23 #Javascript
You might like
基于Windows下Apache PHP5.3.1安装教程
2010/01/08 PHP
《PHP编程最快明白》第五讲:php目录、文件操作
2010/11/01 PHP
php处理json时中文问题的解决方法
2011/04/12 PHP
PHP命名空间(Namespace)的使用详解
2013/05/04 PHP
CodeIgniter读写分离实现方法详解
2016/01/20 PHP
PHP和MYSQL实现分页导航思路详解
2017/04/11 PHP
js实现的真正的iframe高度自适应(兼容IE,FF,Opera)
2010/03/07 Javascript
让图片跳跃起来  javascript图片轮播特效
2016/02/16 Javascript
简单讲解AngularJS的Routing路由的定义与使用
2016/03/05 Javascript
AngularJS 依赖注入详解及示例代码
2016/08/17 Javascript
javascript的函数劫持浅析
2016/09/26 Javascript
浅谈Nodejs中的作用域问题
2016/12/26 NodeJs
原生JavaScrpit中异步请求Ajax实现方法
2017/11/03 Javascript
vue 中directive功能的简单实现
2018/01/05 Javascript
深入理解JavaScript和TypeScript中的class
2018/04/22 Javascript
微信小程序授权登录解决方案的代码实例(含未通过授权解决方案)
2019/05/10 Javascript
微信小程序获取位置展示地图并标注信息的实例代码
2019/09/01 Javascript
Vue实例的对象参数options的几个常用选项详解
2019/11/08 Javascript
微信小程序实现比较功能的方法汇总(五种方法)
2020/03/07 Javascript
JavaScript实现简单的图片切换功能(实例代码)
2020/04/10 Javascript
python中偏函数partial用法实例分析
2015/07/08 Python
jupyter安装小结
2016/03/13 Python
Python实现多进程共享数据的方法分析
2017/12/04 Python
Python人工智能之路 jieba gensim 最好别分家之最简单的相似度实现
2019/08/13 Python
pytorch中的卷积和池化计算方式详解
2020/01/03 Python
Python 通过监听端口实现唯一脚本运行方式
2020/05/05 Python
基于Python采集爬取微信公众号历史数据
2020/11/27 Python
Julep官网:美容产品和指甲油
2017/02/25 全球购物
网吧最新创业计划书范文
2014/03/27 职场文书
李白故里导游词
2015/02/12 职场文书
部门经理助理岗位职责
2015/04/13 职场文书
离婚被告答辩状
2015/05/22 职场文书
六一文艺汇演主持词
2015/06/30 职场文书
陶瓷类经典广告语集锦
2019/10/25 职场文书
整理Python中常用的conda命令操作
2021/06/15 Python
Apache Pulsar结合Hudi构建Lakehouse方案分析
2022/03/31 Servers