本周工作思考
USE1.5项目开发中一些思考,前端编程不仅仅是拼装组件的思考(二)
USE在实现中一些功能模块和学习平台业务中的功能模块类似大不相同,这就涉及到4类技术话题:
对现有业务如何最大限度的复用
如何对现有功能进行持续性扩展而对现有功能的质量影响最小
如何最大限度的降低新功能的开发成本
在持续迭代中如何保持和提升功能和代码的质量
这四个问题是相互影响,相互制约的,研发过程中的基础工程建设基本都是围绕这四个问题的推进而进行的。
这次项目里我看了很多USE相关的代码,我发现最大的问题是对自定义Hook的使用不够充分,这导致很多组件的复用粒度,迭代方式,可拆解性,重构性都或多或少的存在一些固有的问题。
问题一,业务类的自定义hook太少
在React18的组件体系里,通常有两种可用的复用方向,一个方向是组件,一个Hook的方向,Hook自从概念的提升就伴随着很多争议,认可的人们认为这是一个非常精妙的设计,不认可的人们则认为Hook把逻辑拆的七零八散(大家可以看早期的React中关于Hook概念的讨论),当然在React的世界里,关于Hook哲学的讨论是React社区的顶层设计,我们作为该技术的普通使用者顶多算是“吃瓜观众”。随着迭代和发展,前端业务估计90%左右的代码逻辑都是基于Hook的,特别是useState和useEffect。前端工程师都知道React的组件哲学是UI = f(state),状态是组件的基础,而useState和useEffect是管理状态的内置hook,而自定义是基于业务逻辑的对useState和useEffect的封装和管理。
现有的很多hook都是无具体业务属性的自定义hook,目的是通用式的复用,如通用数据请求,通用Promise的处理,通用的事件处理,整体上看是ahook这类库在我们业务里的补充和增加
反观前端代码有数以万计的组件,但是自定义hook可能只有数百个,从业务复杂度上看,很多组件使用了近十多个useState,这些状态相互影响,useEffect的deps甚至也有数十个,这种情况意味需要使用自定义hooh把这个组件中的状态分组,聚类,拆分,让组件中的状态的职责更明确,想办法减少组件中的状态的个数,这个是开发复杂组件的首要技术要求。这样从另一个角度说明我们对类似复杂组件的开发和自定义hook存在认知上不足。
问题二ahook使用的不够深入
同组件一样,React社区也存在各种开源的自定义Hook库,现在在使用的是ahook,里面包括常用的非具体业务领域内的各种hook,比如组件生命周期,内置 hooks 的增强 ,规避闭包带来的值不是最新值,事件相关,计时器,函数辅助等等
在很多业务组件里有很多自己实现的方法,比如计时器,比如事件绑定,这些其实ahook理由更完善的实现,包括我在内的很多前端开发工程师其实没用熟这个库,导致了很多自造的轮子,而且也不太完善的轮子
对于引入的库一定要用熟用透,开发中不要热衷于引入各种库,目前就有一些重复在功能上有重叠的各种库,增加了代码的学习成本,也让整个js代码增加了不少,增加一个库意味着团队成员都要自己学一遍,大家可以想想这个成本,即便有AI可以帮你提升效率,但目前还是要花一些时间在上面,从个人技术成长角度来说,每个库都学一点皮毛,不如把一个库研究透彻,应用熟练,这样更容易举一反三,融汇贯通。
问题三业务逻辑意识不到要用hook封装
自定义hook的目的不仅仅是封装,自定义hook是作为和组件搭配使用的基本工程方法而存在的,这个目的也存在hook概念的早期讨论中,就像JavaScript中的函数一样,很多时候写函数不仅仅是复用,因为他们也意味着更方便的迭代,更可控的质量,更可靠的使用,更易读的代码,它们带来的好处是多方面的
开发过程中,有常见的几类代码很难维护:
业务逻辑和UI紧密耦合,分不清那些是控制UI的,哪些是控制业务,哪些是既要控制UI也要控制业务的,这种情况下,以我的经验,这种组件的代码行数低于200,勉强维护没啥问题,如果多于200行,维护起来就要费点心思了,至少不那么不轻松。
状态多且状态相关依赖,这种不多说了,上面有过描述,此处不赘述
极其简洁抽象,这类代码像是秀技,也可以说对业务对团队没有考虑,既没有考虑团队的平均技术能力,也没有考虑业务后续的迭代维护情况。看这类代码,就像看某些艺术家的画,每个颜色每个绘画元素你都熟悉,合在一起,想破脑袋也不知道画的啥意思
开发中要尽量规避这些情况,很多bug是出现在这几类的代码上。有时候出现线上问题给客户造成问题,大家都觉得很自责,但也不免嘀咕,开发伙伴心里可能会想, 测试为啥没测到这个点,测试伙伴心里可能会想,这么简单的功能,开发怎么搞出个这么个bug,产品和客户界面的伙伴可能会想,这帮研发开发的东西太不靠谱了。其实质量保障是一个体系性的工作,每一个环节都非常重要,但是代码的品质是产品质量的基本保障,原材料级别的质量保证才使得所有后续环节有价值,可持续。