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 的选择就只有这三个:

  1. 重写所有 class 组件,转化为 hooks
  2. 原 class 组件不懂,新组件使用 hooks
  3. 原封不动,新组件依旧使用 class 开发

  每个选择都是有各自的考虑的,比如第一个选择考虑的是成本较高,第三个选择是想保持稳定以及开发时间。

  建议假如是新项目或刚刚起步,就全篇使用 hooks 开发(第二种方案),如果已经是稳定上线的项目的迭代,就可以在迭代的组件中使用 hooks,但是如果你的团队需要考虑学习时间成本,本身开发时间较紧张,那么还是建议依旧使用 class 组件进行接下来的开发,因为 class 已经很久了,你的团队一定已经有了一套比较完备的方案与流程来进行接下来的开发,它会让你节省不少的时间。

本文使用 mdnice 排版

使用 React hooks 转化 class 的一些思考的更多相关文章

  1. React hooks实践

    前言 最近要对旧的项目进行重构,统一使用全新的react技术栈.同时,我们也决定尝试使用React hooks来进行开发,但是,由于React hooks崇尚的是使用(也只能使用)function c ...

  2. react新特性 react hooks

    本文介绍的是react新特性react hooks,本文面向的是有一定react开发经验的小伙伴,如果你对react还不是很熟悉的话我建议你先学习react并多多联系. 首先我们都知道react有3种 ...

  3. 30分钟精通React今年最劲爆的新特性——React Hooks

    你还在为该使用无状态组件(Function)还是有状态组件(Class)而烦恼吗? --拥有了hooks,你再也不需要写Class了,你的所有组件都将是Function. 你还在为搞不清使用哪个生命周 ...

  4. React Hooks 实现和由来以及解决的问题

    与React类组件相比,React函数式组件究竟有何不同? 一般的回答都是: 类组件比函数式组件多了更多的特性,比如 state,那如果有 Hooks 之后呢? 函数组件性能比类组件好,但是在现代浏览 ...

  5. 蒲公英 · JELLY技术周刊 Vol.17: 90 行代码实现 React Hooks

    蒲公英 · JELLY技术周刊 Vol.17 React Hooks 相信大家都不陌生,自被设计出以来就备受好评,在很多场景中都有极高的使用率,其中原理更是很多大厂面试中的必考题,很多朋友都能够如数家 ...

  6. 蒲公英 · JELLY技术周刊 Vol.21 -- 技术周刊 · React Hooks vs Vue 3 + Composition API

    蒲公英 · JELLY技术周刊 Vol.21 选 React 还是 Vue,每个人心中都会有自己的答案,有很多理由去 pick 心水的框架,但是当我们扪心自问,我们真的可以公正的来评价这两者之间的差异 ...

  7. 你真的会用react hooks?看看eslint警告吧!(如何发请求、提升代码性能等问题)

    前言 看过几个react hooks 的项目,控制台上几百条警告,大多是语法不规范,react hooks 使用有风险,也有项目直接没开eslint.当然,这些项目肯定跑起来了,因为react自身或者 ...

  8. 通过 React Hooks 声明式地使用 setInterval

    本文由云+社区发表 作者:Dan Abramov 接触 React Hooks 一定时间的你,也许会碰到一个神奇的问题: setInterval 用起来没你想的简单. Ryan Florence 在他 ...

  9. 初探React Hooks & SSR改造

    Hooks React v16.8 发布了 Hooks,其主要是解决跨组件.组件复用的状态管理问题. 在 class 中组件的状态封装在对象中,然后通过单向数据流来组织组件间的状态交互.这种模式下,跨 ...

随机推荐

  1. K - Two Contests

    题目连接:https://atcoder.jp/contests/agc040/tasks/agc040_b 大佬题解:https://blog.csdn.net/duanghaha/article/ ...

  2. 小L的直线

    小学时期的小L发现自己很有艺术细胞,于是买了一块画板,但是他的绘画水平使得他只能连接两点画出一条线段.有一天他决定在一张有n个点的图上作画,即他可以把这n个点任意连接.大家认为平行线是非常不美观的,于 ...

  3. LCA基础 附例题(落谷)

    https://www.luogu.org/problemnew/solution/P3379 LCA叫做最短公共祖先,用来求距离树上两个节点最近的公共点: 常用倍增算法: #include<i ...

  4. vue-element-admin执行npm install 报错

    如果你出现这类报错: 那么恭喜你,因为这个问题很好解决. ----------------------- 解决方法: git config --global url."https://&qu ...

  5. [转]ThinkCMF框架任意内容包含漏洞分析复现

    0x00 简介 ThinkCMF是一款基于PHP+MYSQL开发的中文内容管理框架,底层采用ThinkPHP3.2.3构建.ThinkCMF提出灵活的应用机制,框架自身提供基础的管理功能,而开发者可以 ...

  6. Springboot:员工管理之国际化(十(3))

    1:IDEA编码设置UTF-8 2:创建国际化文件 i18n\login.properties #默认语言 i18n\login_en_US.properties #英文语言 i18n\login_z ...

  7. 【轮询】【ajax】【js】【spring boot】ajax超时请求:前端轮询处理超时请求解决方案 + spring boot服务设置接口超时时间的设置

    场景描述: ajax设置timeout在本机测试有效,但是在生产环境等外网环境无效的问题 1.ajax的timeout属性设置 前端请求超时事件[网络连接不稳定时候,就无效了] var data = ...

  8. Jest 前端单元测试工具

    Jest和enzyme 前端单元测试工具 什么是Jest? Jest是一个令人愉悦的JavaScript测试框架,其重点是简单性. 它适用于使用以下项目的项目:Babel,TypeScript,Nod ...

  9. h5前端animate等js特效问题汇总

    1.jq中的animate不要重复大量使用,会导致内存溢出或泄漏,很直观的现象就是手机发热太严重: 2.input 的button类型的去掉默认样式并换颜色: -webkit-appearance:n ...

  10. IDEA 之 ERROR:无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core]

    问题描述:在使用IDEA对JSTL进行测试时出现error:无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core] ...