想要一份senior工作,务必要读 React 源代码吗?

4,587 阅读4分钟

打算试着记录下每日的感悟,有趣的库,有趣的文,有趣的事,和思考。走一路,留下些脚印。

关于读源代码

这段面试了一些。很多公司都会甩这个问题给你:读过 React 的源代码吗? 答曰:没读过。瞬间感到自己的自信心掉了一块。网上也不乏各种分析源代码的文章和精读,只是我还是没有那个勇气和兴趣去读如此成熟的一个库的源代码,甚至想读也不知从何读起。

但为了面试,似乎这是必须的?

于是跑上 Reddit 发了一贴,想问问看老外们是怎么看这个问题的。

十分钟过去了,得到一个回复,全文如下:

But I can't bring myself on reading the source code of such a mature project, I don't even know where to begin.

Don't feel bad. I think every one of us on the core team has parts of React that we have not read (or at least are only vaguely familiar with).

So I wonder, especially for those who've read the code, is it important to read the source code if you are searching for a senior job?

My feeling is a strong "no" for this one. You don't need to read the source code to use React effectively. The docs should be sufficient! If they aren't, we've done a poor job.

简单翻译如下:

我读不来源码,都不知道从哪儿开始

不要感到难过,我们React核心开发团队的每个人都或多或少有一部分源代码没有读过。

想问一下读过的人,找一份senior工作,读源代码是否必要?

我个人强烈认为“No”。即使不读源代码也能高效使用 React。官方文档应该已经足够了!如果不够,说明我们的工作没做好。

哈哈,惊不惊喜,意不意外。逛贴吧撞上facebook大佬。大佬表态了,估计说该读的人也都退散了。没听到反面的声音也算一大遗憾,当然比不过收到这个回复的惊喜。

个人观点是:

  1. 了解生命周期
  2. 了解diff的算法(文档 reconciliation )

就算React是一个黑箱子,知道它运作的规则可以自我解答很多“这样写影不影响性能”的疑问。

第二个回复的 acemarke 是redux文档的维护者,经常热心解答各种问题,他说自己没读过源码让我吃了一惊。同时决定暂时不去读了。毕竟还有那么多想要做的事,想要学的东西。前端的更新速度真是太疯狂了。让面试见鬼去吧(说笑)。

问题

  1. diff 的算法复杂度是多少?
  2. 如果两个子元素的key一样,React的diff算法会怎么做(没法用key区分哪个是哪个了)?

第一题 O(n) 。第二题恳请知道答案的各位大牛慷慨留言 :D

补充:拿了几个demo试验了一下,key相同的情况渲染结果很不稳定,最简单数组map到div似乎能正常渲染,但拿todolist试验发现只要出现重复key只会渲染第一条。有趣的是,连warning文字在几个情况下也有些许不同(也可能是react版本不同造成),但大致的意思是:重复key会引起未知状况,带重复key的元素渲染有可能会被忽视,也有可能出现重复。这里果然是要看源代码才能知道内部是怎么处理的。

问题

  1. 可以在 React 组件里定义 React 组件吗?
  2. 可以在 render() 函数里定义 React 组件吗?

答案是:可以和不可以。React组件可以作为另一个组件的实例方法。感觉就是函数里面定义函数,没问题。

但是在render() 里定义 React 组件会出事。这里就涉及到diff的算法的第一假设,如果两次 render 的组件不同, 那React就会销毁原元素,然后重新渲染新的元素。这不仅仅是性能,所有组件及其子组件的state都被销毁了。那么为啥在render() 里定义组件会让 render认为组件不同呢?因为组件是一个class或者是function,js里对比两个class 或者是 function 是否相等是看两者的引用(reference),所以必然不相等。

const a = class {}
const b = class {}
a === b // false

一般不会有人在组件里定义组件(这么做是可以的),更别提在render() 函数里了。不过我确实遇到了这样的情况,比如在render()里使用HOC。

最近忙就写这些吧。

最后推荐一篇早上看了开我眼界的文章:用webflow设计App

一直以为像webflow这样的工具是给不会css的设计师写网页用的。但是一个使用 React + GraphQL 框架的公司也决定使用webflow,而且完美整合。也许像webflow一样的工具会是前端开发的未来呢。

我写的其他专栏文章列表 传送门