使用 React hooks 转化 class 的一些思考
Hooks 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。
使用 React hooks 转化 class 的一些思考
Hooks 其实已经是大势所趋的一个技术了,作为一个可能是 React,甚至是 JS 史上都是一个比较伟大的发明,Hooks 已经被大部分中小型公司所接受并尝试使用,但是对于大中型公司来讲,从 class 组件移植 Hooks 的成本太高,不能像其他公司一样随心所欲地拥抱新技术,所以我们对于 Hooks 的讨论,应该考虑的比较全面,才能更好的了解这个技术,以及是否应该在项目中尝试这一新技术。
在论坛上我也有和一个小伙伴对此有一个讨论,感谢@无怨,前代 react 项目 class 转 hooks 的必要性。其实大家对 hook 都是认可的,但是对于重写 class 的成本方面还是望而却步的,react 官方也不希望因为这个使得新版本使用者剧减,所以暂时还是会兼容 class 组件的写法。
所以其实对于是重写部分还是只有新组件使用 hook,大家都还是比较犹豫的,对这种选择来看,我们必须实际考虑成本-产出比,所以我们这篇就具体讨论成本与产出,以及可行的方案吧~
首先咱们来看看成本吧
修改成本
作为 React 16.8 新增特性,一些第三方的库可能还暂时无法兼容 Hooks,比如 React Redux 从 v7.1.0 才开始支持 Hook API 并暴露了 useDispatch 和 useSelector 等,而 React Router 从 v5.1 开始支持 hooks。所以如果我们的项目中 Redux 和 Router 版本不够的话,可能需要评价是否有必要升级和升级后可能带来的问题。
再一点,业务逻辑内的代码拆分。在 hooks 中,是不太建议将 state 放置于同一个 state 中的,考虑到性能及区域更新机制,既 state 切分成多个 state 变量,每个变量包含的不同值会在同时发生变化。建议是将 state 根据业务逻辑,拆分成多个 useState。
这样虽然会增加组件的性能,毕竟每次更新都只是更新一部分组件,但是对于重写 class,我们还需要深入每一个的 class,探究里面 state 的联系、机制等等,是一个较大的阻碍与挑战。
还有一点,暂时的话,hooks 必须传递 Props 的方式获取根组件 App 中的 state,意思就是如果想使用主 reducer 库中的 state 的话,必须使用 props 传递进来(或通过把 state 也装进 Context 来解决,但是空间成本太大了),只有改变其值才可以 dispatch 来修改
修改成本可以算成本中最大的一环了,事实上每个 class 组件都可能有非常多的逻辑、状态,各种状态可能都有内在的一些联系。重新去理解这部分代码并重新构建 hooks,其实是一件非常大的挑战,所以本身我暂时对重写 class 到 hooks 是持观望态度,当 React 官方没有一定的苗头出来说不支持 class 写法前,重写的动力确实是不够充足。
学习成本
hook 本身其实和 class 一样,都是关于本身这个组件的实现细节,重不重写其实对书写正常业务是完全没有影响的(不考虑性能方面的话)。所以 hooks 对于 class 的重写还是会有一定的学习成本在内,毕竟这边要考虑本身与日后入职的小伙伴对这块的熟练度。
时间成本
按我的预估,对一个完整项目中,class 组件转 hooks,以及部分文件结构整理的时间可能要一个多月(以我的微薄水平),用户看不见明显的功能、UI 修改,不得不说这部分的时间支出是比较大的。
而如果是原 class 保留不动,新组件使用 hooks 的话,时间成本其实就减少很多了,毕竟新的组件也是从无到有搭建起来,多花的时间可能基本集中在前期对新增 hooks 的结构整理,以及对 redux 仓库的有机结合上,当结构完善,有咱们自己的一套书写模式之后,就可以达到现在书写 class 组件的速度与体验了。
我们能够得到什么?
OK 我们说完了成本,来看看 Hooks 可以带给我们什么?
假设是原 class 组件保留,新建 hooks
hooks 是一个 React 官方的新特性,Hook 的使用是完全能代替 class 组件的使用,也肯定对其有一个比较大的意义在其中,事实上他们内部原理都是 diff and patch,性能方面差距几乎是可以忽略不计的,但是我的理解是,hooks 更倾向于函数式编程,class 则更倾向于面向对象编程。这是一个大趋势。
在新的组件中使用 hooks,其实写过之后就能体会到为什么有人说Hooks更骚,class更蠢
了。它将所有类似生命周期函数都可以用一个 useEffect 来进行模拟,不会使得自己的逻辑大量分布在 class 的各个角落,大幅度集成业务逻辑代码。
这是新技术。对没错,我认为新技术本身就是一个我们能够看到的"获得"。在以前我们也会觉得 Jquery 非常好用,以后都会使用这种方式开发,但是后来出现了 webpack,出现了 React、Vue,我们的代码书写形式又变了。新技术的出现本身就是一种信号,只要它接受住了大量业务情况的考验,他的存在就是有某种值得值得去获取的优点,比如后来的组件化、工程化、解耦合等概念。
假设是重写 class 组件
除了上述优点外,其实就没有过多的其他优点了,只是整个项目的文件结构会更紧凑,毕竟不用兼容 class 写法与 hooks 写法,但是对于性能来说,是没有那种显著提升的。
额外
性能方面的差距其实是几乎可以忽略不计的,但是函数式编程是越来越火起来的思想,同时 Hooks 从诞生开始就一直在致力于增强其性能,讨论活跃度也足够高,所以可预想的未来内,hooks 性能方面应该会有一个比较大的飞跃。所以这方面也应该是一个可参考的获得。
方案
说了这么多,其实我们关于 hooks 的选择就只有这三个:
重写所有 class 组件,转化为 hooks 原 class 组件不懂,新组件使用 hooks 原封不动,新组件依旧使用 class 开发
每个选择都是有各自的考虑的,比如第一个选择考虑的是成本较高,第三个选择是想保持稳定以及开发时间。
建议假如是新项目或刚刚起步,就全篇使用 hooks 开发(第二种方案),如果已经是稳定上线的项目的迭代,就可以在迭代的组件中使用 hooks,但是如果你的团队需要考虑学习时间成本,本身开发时间较紧张,那么还是建议依旧使用 class 组件进行接下来的开发,因为 class 已经很久了,你的团队一定已经有了一套比较完备的方案与流程来进行接下来的开发,它会让你节省不少的时间。
本文使用 mdnice 排版
使用 React hooks 转化 class 的一些思考的更多相关文章
- React hooks实践
前言 最近要对旧的项目进行重构,统一使用全新的react技术栈.同时,我们也决定尝试使用React hooks来进行开发,但是,由于React hooks崇尚的是使用(也只能使用)function c ...
- react新特性 react hooks
本文介绍的是react新特性react hooks,本文面向的是有一定react开发经验的小伙伴,如果你对react还不是很熟悉的话我建议你先学习react并多多联系. 首先我们都知道react有3种 ...
- 30分钟精通React今年最劲爆的新特性——React Hooks
你还在为该使用无状态组件(Function)还是有状态组件(Class)而烦恼吗? --拥有了hooks,你再也不需要写Class了,你的所有组件都将是Function. 你还在为搞不清使用哪个生命周 ...
- React Hooks 实现和由来以及解决的问题
与React类组件相比,React函数式组件究竟有何不同? 一般的回答都是: 类组件比函数式组件多了更多的特性,比如 state,那如果有 Hooks 之后呢? 函数组件性能比类组件好,但是在现代浏览 ...
- 蒲公英 · JELLY技术周刊 Vol.17: 90 行代码实现 React Hooks
蒲公英 · JELLY技术周刊 Vol.17 React Hooks 相信大家都不陌生,自被设计出以来就备受好评,在很多场景中都有极高的使用率,其中原理更是很多大厂面试中的必考题,很多朋友都能够如数家 ...
- 蒲公英 · JELLY技术周刊 Vol.21 -- 技术周刊 · React Hooks vs Vue 3 + Composition API
蒲公英 · JELLY技术周刊 Vol.21 选 React 还是 Vue,每个人心中都会有自己的答案,有很多理由去 pick 心水的框架,但是当我们扪心自问,我们真的可以公正的来评价这两者之间的差异 ...
- 你真的会用react hooks?看看eslint警告吧!(如何发请求、提升代码性能等问题)
前言 看过几个react hooks 的项目,控制台上几百条警告,大多是语法不规范,react hooks 使用有风险,也有项目直接没开eslint.当然,这些项目肯定跑起来了,因为react自身或者 ...
- 通过 React Hooks 声明式地使用 setInterval
本文由云+社区发表 作者:Dan Abramov 接触 React Hooks 一定时间的你,也许会碰到一个神奇的问题: setInterval 用起来没你想的简单. Ryan Florence 在他 ...
- 初探React Hooks & SSR改造
Hooks React v16.8 发布了 Hooks,其主要是解决跨组件.组件复用的状态管理问题. 在 class 中组件的状态封装在对象中,然后通过单向数据流来组织组件间的状态交互.这种模式下,跨 ...
随机推荐
- 用Python做一个知乎沙雕问题总结
用Python做一个知乎沙雕问题总结 松鼠爱吃饼干2020-04-01 13:40 前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以 ...
- Python语法详解
python语法解析 目录 python语法解析 一.顺序结构 二.分支结构 2.1 if 的基本语法 2.2 if 的基本应用 三.循环结构 3.1 while 语法 3.1.1 语法结束条件 3. ...
- S - Primitive Primes CodeForces - 1316C 数学
数学题 在f(x)和g(x)的系数里找到第一个不是p的倍数的数,然后相加就是答案 为什么? 设x1为f(x)中第一个不是p的倍数的系数,x2为g(x)...... x1+x2前的系数为(a[x1+x2 ...
- F - Bone Collector
Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like ...
- js拼接onclick方法字符串参数解决方法
onclick = contentmap("'+useridarr[i]+'")
- JavaScript数据类型 —— 基础语法(2)
JavaScript基础语法(2) 数据类型 js中有六种数据类型,包括五种基本数据类型(Number,String,Boolean,Undefined,Null),和一种复杂数据类型(Object) ...
- 处理数字的类 —— Math类 、 Random类 、 BigDecimal类 与 BigInteger类
在我们学习C语言时,我们处理数据时要调用很多函数,那么,Java也有很多的方法可以来处理数值的类. 那么,在本篇博文中,本人就来讲解三个用于处理数值的类 -- Math类 . Random类 与 Bi ...
- 【学习笔记】splay入门(更新中)
声明:本博客所有随笔都参照了网络资料或其他博客,仅为博主想加深理解而写,如有疑问欢迎与博主讨论✧。٩(ˊᗜˋ)و✧*。 前言 终于学习了 spaly \(splay\) !听说了很久,因为dalao总 ...
- spark 集群优化
只有满怀自信的人,能在任何地方都怀有自信,沉浸在生活中,并认识自己的意志. 前言 最近公司有一个生产的小集群,专门用于运行spark作业.但是偶尔会因为nn或dn压力过大而导致作业checkpoint ...
- SpringCloud-Gateway 网关路由、断言、过滤
Gateway 简介 是什么? Spring Cloud 全家桶中有个很重要的组件:网关.在 1.x 版本中使用的是 Zuul 网关,但是到了 2.x,由于Zuul的升级不断跳票,Spring Clo ...