这两天几个群都在传尤大喷 React 文档的截图,并且引起了热烈的讨论。然后就有人在问,是不是 React 真的那么坑。
作为一个 React 深度使用者,觉得不应该让新学 React 的朋友留下这样一个刻板印象,所以我结合自身对于 React 的使用体验,反驳一下他的观点。
看一下尤大是怎么喷的。先是有个人发文吹了一波 React 新官网写得很用心。
然后尤大不知道为什么怨念会这么深,就说 React 挖下了许多艰深复杂的坑,用了夸张的手法来特意强调了这些坑的严重性。甚至用了 PUA 这样的词来刻意强调自己的观点。
然后又说:React 最成功的地方在于塑造了一种几近于 cult 的凝聚力...
好巧不巧,我刚好认识这个单词...
cult:邪教
如果我说尤大有点上头、激进、极端,这应该不算是夸张的评价吧?我记得他以前说国内喷子多,技术氛围没有国外好,他这是在干嘛?说 React 用户是邪教、是被 PUA,这不算喷人吗?
一、截图中的案例
首先跟大家明确一下,截图中的案例,完全不是 React 的坑点。而应该算是 React 的优点之一。
因为当 React 中的状态发生变化时,会导致组件函数重新执行。因此,当我们需要一个计算属性时,不用做特别的处理和定义,正常使用即可。
function Form() {
const [firstName, setFirstName] = useState('Taylor');
const [lastName, setLastName] = useState('Swift');
// ✅ Good: calculated during rendering
const fullName = firstName + ' ' + lastName;
// ...
}
例如使用 useEffect 去监听 state,这是冗余的操作。然后给出了错误示范。
function Form() {
const [firstName, setFirstName] = useState('Taylor');
const [lastName, setLastName] = useState('Swift');
// 🔴 Avoid: redundant state and unnecessary Effect
const [fullName, setFullName] = useState('');
useEffect(() => {
setFullName(firstName + ' ' + lastName);
}, [firstName, lastName]);
// ...
}
所以这里只是列举出来部分使用者的错误示范而已,压根算不上是一个坑点。如果这也算坑点,我可以在别的框架使用者的代码里找到一大堆错误示范,相互攻击就完事了,对不?
二、React 弱侵入性
React 始终保持了对 JavaScript 的弱侵入性。我认为这是一个非常大的优点。也就是说,当你使用 React 开发时,实际上用到的语法相对比较少,就算是你学习 React 也不会接触到太多的官方 API。
弱侵入性带来的一个巨大的好处是,我们在开发时可以顺利植入我自己的开发理念。比如,你觉得 React 没有做依赖收集,是不好的,那么你就可以写一个状态管理去做依赖收集。Mobx 就是做这个事情的。
又或者,你觉得 React 提供的全局状态管理不如你的心意,你就可以自己封装一个发布订阅,结合自定义 hook 也能方便的订阅每一个组件。
这样的自由度一定是会受到 React 深度使用者欢迎的。这也是 React 生态百花齐放的原因之一。不知道别人会怎么样,但是我觉得我作为开发者,我非常喜欢多种开发思想相互碰撞的氛围。
三、闭包陷阱?
有的人觉得闭包陷阱是一个坑。
实际上,这个所谓的闭包陷阱这个词,不应该与 React 绑定在一起。因为闭包本身就是 JS 自身的特性。就算没有 React,许多人也觉得闭包难以理解。而且作为前端开发,我觉得应该做的事情是去掌握闭包的机制和逻辑,而不是觉得闭包这个东西我理解不了,就认为它不好。
闭包的特性让 JS 的能力变得非常强大,甚至你很多时候也在不知不觉中利用闭包来达到你的目的。许多别的开发语言中,也引入了闭包的机制,说明闭包是经历过时间沉淀的方案。
如果一个知识点,理解起来比较困难,然后我们就给他戴上心智负担重的帽子,然后把他作为一个缺点去不断批评他,这算是正常的想法吗?
四、性能不好?
Vue 重依赖收集,轻/无 UI diff.
React 无依赖收集, 重 UI diff.
也就是说,当 Vue 的数据变得庞大和复杂,他依然会有不小的性能压力。因此 Vue 的性能优化策略应该是集中在如何简化数据结构上。而 React 的优化重点,在如何减轻 diff 压力上。
谁也不能否认,有人能合理利用 React 的机制,编写出来一套性能比 Vue 更好的项目。只是说,做到这个事情对于 React 新玩家来说,有点困难而已。
Vue 均衡性能更好,React 性能上限更高。既然各有优劣,他只是一个不同人群的取舍问题,但你绝对不能说,这是 React 艰深复杂的坑点。
五、新手友好?
尤大一直以框架对新手友好作为一个重要的判断标准来证明一个框架是否优秀。但是扪心自问,各位前端开发们,你们真的会一直认为一门技术对新手友好,就一定是更好的吗?
我们在群里实际上还有另外一个观点。
当你还是新人的时候,你希望你学的东西简单,能快速上手。但是当你学成之后,你又担心他太简单,会的人太多,自己毫无竞争力。
我猜测许多人的心态,会经历这样的变化。所以我遇到很多 Vue 开发者,在使用了几年 Vue 之后,也会有很强烈的想法学习一下 React
实际上,在我看来,当我们技术能力逐渐变得更强,我掌握的技术,能够支撑起更高的上限,这也是一门框架不可忽视的巨大优势。在两者之间取得一个平衡,我认为这一点上,React 比 Vue 要做的好。
我们不能因为对新手友好,就忽略了 React 上限更高这个事实。而且事实上,现在已经有同学认为, Vue3 的学习成本,已经高于 react hooks。
六、Vue3 的破坏性更新
尤大说,Vue3 的破坏性更新,是他们团队犯的错误。但真的是决策失误吗?
我看未必。因为你不得不承认,事实上,你单看 Vue2 你就知道,Vue3 的出现,更多的是被逼无奈。
有两个重要因素导致了 Vue2 承担了巨大的压力。
一个因素是 TS 被广泛接纳。导致了 Vue2 不支持 TS 成为了一个无法被反驳的缺陷。即使是现在的 Vue3,也依然有人觉得它对 TS 的支持并没有做到尽善尽美。
另外一个就是 React hooks 的出现,让 Vue2 的差距被明显拉开。所以你才会看到新的 Vue 语法,从某种程度上,跟 React hooks 长得很相似。
这两个因素组合在一起,催生了 Vue3 长成现在的样子。
然而破坏性更新是有代价。现在依然有大量的团队无法成功把项目从 Vue2 升级到 Vue3,这才是极大的坑点。
六、最后
写这篇文章,无意去过度争论 Vue 和 React 到底谁更好,因为在实际场景中做技术选型,要考虑的因素还包括技术之外的东西,这些外因甚至比技术本身更加重要。比如,我一直想去的那个团队,用的是 React,这样的理由,更加能左右一个人的决定。
主要的目的是不希望被很多人认为,React 像尤大说的那样,真的有很多艰深复杂的坑,我不认同这样的说法。也不希望吹一下 React 就被当成邪教。我觉得好的东西,夸一下这是很正常的事情。