[译] React 的今天和明天 I —— 现状和问题

7,729 阅读10分钟

2018年 11 月 30 日更新,第二部分已经更新:[译] React 的今天和明天(图文版) —— 第二部分 。前两部分中英双语字幕视频已经发布:【React Conf 2018】React 的今天和明天中英文双字幕

React 的今天和明天 I —— 现状和问题

2018-11-08 4 20 29

早上好。大家好,欢迎来到 React 大会。今天来到这里我感到非常激动。我非常高兴可以给你们做开场演讲。

我是 Sophie Alpert,个人主页是 sophiebits.com。我是 Facebook 的 React 核心小组的开发经理。

2018-11-08 4 20 59

React 的今天

你们正在使用的 React 做的很好。我们在 npm 的下载量一年内增加了 70%。 React Dev Tools 在 Chrome 开发者工具扩展程序的安装量达到了 125 万。

2018-11-08 4 21 47

这是使用 React 的公司列表。此时此刻,这个列表已经非常长了,我们很难说清每年使用 React 的公司的变化。

2018-11-08 4 22 08

我们来看另一组数据,我们来看看 Google 趋势, 它可以反映出网络搜索的流量。可以看到,React 的搜索量一直在增加。 希望这个数据表示有更多的人在使用 React,而不是 React 变得更加令人困惑了。(笑声)

2018-11-08 4 22 28

嗯,为了做比较,我们比较了 jQuery 的搜索量,我们的搜索量刚刚在历史上首次超越了 jQuery。(欢呼和掌声)但这也表明,我们仍然有很多成长的空间。

2018-11-08 4 23 05

我在写这个演讲时被耽搁了一会儿。 因为我比较好奇 React 还比什么更流行。 哎呀。(笑声)当我开了个玩笑。嗯,我发现 React 比可再生能源(renewable energy)更流行。(笑声)

2018-11-08 4 32 14

React 也比橙汁(orange juice)更流行。(笑声)想想橙汁是多么常用啊,是吧。

2018-11-08 4 32 32

而且 React 比可再生能源和橙汁加在一起更流行。所以我认为我们有理由感到非常自豪。

2018-11-08 4 32 56

React 的使命

但是除了这些数字,我今天真正想要讲的是 React 的使命。呃,自从 2013 年 React 发布以来,我们首要的目标和使命就是:帮助开发者更容易地构建卓越的 UI。

2018-11-08 4 35 26

所以当我们想要增加新的特性时,我们通常都是要经过深思熟虑。当我们决定是否增加新的 API 时,我们需要考虑非常多的事情。如果增加新的 API 能够让你做到一些以前做不到的事情;如果可以显著简化组件里的代码和类库,让你的工作量减小,用户下载更少的代码,那新增 API 就是有价值的。或者如果新增 API 能够帮助我们做到代码分割的最佳实践,如果能够更容易地将你 app 里面的代码分割成多个包,我们希望你的 app 最终可以运行更快。这也是我们两周之前宣布增加像 React.lazy 这样的 API 的原因。 你们可能已经注意到了这个 API。

2018-11-08 4 52 47

但想想 React 的使命 —— 帮助开发者更容易地构建卓越的 UI。我们有很多方法来实现这个目标。 其中一点是我们尝试简化复杂的东西。如果你看了 Dan Abramov 在冰岛的 JS Conf 上的演讲,你可以抢先看到 "Suspense", "Suspense" 是我们用来显著简化 app 中获取数据请求、代码分割和异步数据依赖的问题。

2018-11-08 4 54 19

另外一个我们尝试去提升 React 的方式就是提升性能。如果你的 app 运行速度更快,你的用户就会更原意使用它。相反的,如果你的 app 反应很慢,速度卡顿,那你的用户肯定不会有很好的体验。因此我们尝试让 React 本身运行的更快,如果 React 开箱就很快,那么你们就会省下很多优化你自己代码的时间。

2018-11-08 4 54 56

最近和提升性能有关的内容,Dan 也在冰岛的 JS Conf 上提到了,我们称其为 "Time Slicing"。"Time Slicing" 可以确保你 app 里面最重要的渲染会最先执行,解除主线程的阻塞,并且能让你的 app 运行地更快速。

2018-11-08 4 55 44

第三种方式是使用开发者工具帮助你 debug ,进而更了解你的 app。一开始,React 就包含了对开发者友好的警告来帮助开发者指出问题,以防开发者没有注意到这些问题。

2018-11-08 4 56 24

而且我们的 React Dev Tools 扩展程序能够让你检查并且 debug 你的组件树。 在 React 16.5 版本,我们引入了一个叫 Profiler 的新特性。它是第二个 ... (我不知道这个遥控器出了什么问题)... 图上的第二个标签栏就是 profiler 标签栏, 它能够帮助我们了解到你的 app 中到底发生了什么,然后更好地优化它。

2018-11-08 4 57 03

所以 Suspense, Time Slicing 和 Profiler 这三个新特性是我们去年一直在做的事情。 我们真的想多说一些关于这三个特性的内容。但是这些并不是我今天在这里想要讲的。大家可以等到明天,Andrew 和 Brian 会在明天早上给大家带来关于这个内容的演讲。

2018-11-08 9 08 56

React 还存在什么坑?

现在我想退一步,让我们来关注一些其他的问题。我想问的是,现在 React 还有什么坑?我总结出了三个问题,想在这里和大家讨论。

2018-11-08 9 10 04

逻辑复用

第一个问题就是多组件间的逻辑复用问题。

2018-11-08 9 10 29

在 React 中我们主要使用组件来构建我们的应用,组件主要有两种主要的模式来复用代码:它们是高阶组件(higher-order components)和渲染属性(render props)。

2018-11-08 9 11 44

这两种模式对于某些场景来说是很好的,但是它们也造成了一个极大的缺点。在更加复杂的场景中,你必须将他们抽离出来去重构你的 app。这会导致一个问题,我称之为”包装地狱“(wrapper hell)。

2018-11-08 9 15 54

嗯,我们经常会看到像这样的组件树。(尖叫和笑声)而且这种嵌套会造成跟踪 app 数据流的困难。如果能够复用这类有状态的逻辑,而不需要修改组件的层级,那肯定是很好的方法,对吧。

巨型组件

第二个我想讲的问题是巨型组件,它的逻辑杂乱无章。我们来看看一个上千行代码的 React 组件,可以看到逻辑分散到了许多不同的生命周期函数中,这样非常难以跟踪。

2018-11-08 9 19 58

我们来看一个例子。这里有一个 class 组件,在它的 componentDidMount 方法,它做了几件事:它订阅了一个数据存储,然后发送了一个网络请求,最后开启了一个定时器。

2018-11-08 9 20 50

那么,如果我们来看 componentWillUnmount 方法,我们会看到基本完全相反的代码:首先需要取消订阅存储,然后取消网络请求,最后停止定时器。

当我们要实现 componentDidUpdate 方法, 里面的逻辑会更加的 tricky。因为你需要比较新旧的属性,然后再一次重复和其他生命周期函数内部相同的任务逻辑。

呃,在这个例子里,每个请求都只有一行,所以说这个例子实际上比你平时看到的组件要简单的多。在真实组件中,逻辑往往会更加错综复杂,因为每个独立的任务分散到了 不同的生命周期函数中,这样会造成困难,举个例子,当你 unmounting 组件时,你可能会忘记清除资源,这非常难以从代码中找到问题。

令人困惑的 Class

第三个坑是 Class。理解 JavaScript 里的 class 会相当 tricky,而且为了能够使用 state 和生命周期,我们要求你们使用 class 组件才能做到。

2018-11-08 9 22 30

如果你用过 function 组件,并且将其转为了 class 组件,并增加了一些 state,你就会知道这个过程需要有大量的样板文件,但是其作用仅仅是用来定义一个 class 组件。大多数初学者以及很多有经验的开发者也都跟我们抱怨过在 class 里面的绑定和转化工作相当令人困惑。我们有必要来关注这个问题。

而且我们经常听说大家并不是非常清楚什么时候使用 function 组件,有一部分原因是他们总会担心早晚需要将这个组件转化为 class 组件。所以你们可能会出现这样的困惑:我也不清楚到底我现在是否应该这么做。

所以我说 class 对于人类来说是很难的,但是不仅仅对于人类而言是这样,我认为 class 对于机器而言也是同样很难。

2018-11-08 9 23 52

如果你看过压缩后的组件文件,可以看到所有的方法名没有被压缩。而且如果你有一个完全没有被使用的方法,它也没有被剔除出去。这是因为在编译时很难准确判断方法是否被使用。

我们还发现 class 使得可靠的热加载变得困难。最后当我们设计一个优化的编译器原型来提升 React 组件性能时,我们发现 class 组件的一些模式使得编译器优化变得更加困难。

总结

所以,我们现在有三个问题:逻辑复用、庞大的组件和 Class。逻辑复用的问题会导致你经常遇到“包装地狱”。庞大组件的原因是由于逻辑分散到了不同的生命周期中。而令人困惑的 class 无论对于人类还是机器来说都是个难题。

2018-11-08 9 22 30

我们认为我们有了一个能够解决以上三个问题的解决方案。我们特别想把这个方案分享给大家。请允许我请出 Dan Abramov 为我们带来接下来的演讲。


传送门


希望看本文视频的同学,可以查看我的这篇文章:React Conf 2018 专题 —— React Today and Tomorrow PART I 视频中英双语字幕,中英双语字幕已经给大家准备好了。我们的 Demo Boy —— Dan Abramov 后面关于 React Hooks 的精彩演讲正在翻译中,欢迎有兴趣的同学联系我一起翻译,让更多的小伙伴能够更快看到 React Conf 2018 的精彩内容。