工作中项目代码重构复盘

在工作中,我们经常面临需要对现有代码进行重构的情况。本篇博客将分享我在最近一次代码重构中的经历和思考过程。我将详细讨论问题的根源、造成的影响,以及我考虑和尝试的各种解决方案。最终,我会分享我选择的方案以及它带来的效果。

重构的动机和背景

背景

我们的项目是一个面向企业的Web应用程序,最初采用craco脚手架构建,整合了React和Typescript技术栈。这个项目从零开始,承载着团队对创新和卓越的追求。随着业务需求的不断扩展和市场环境的快速变化,我们经历了一次重大的项目迭代。 这次迭代不仅包括了UI的全面调整,还涉及到了项目构建工具的升级——我们从craco迁移到了Vite,一个更现代、更快速的工具,极大的提升了项目的开发效率。

尽管项目整体架构经过了这次大规模的更新,但本文将重点探讨一个特定页面的代码逻辑重构。这个页面作为项目的核心功能区域,随着业务逻辑的不断增加,其代码逐渐变得复杂和难以管理。

重构动机

尽管项目的历史相对较短,但核心页面在经历多轮业务需求迭代以及 UI 调整后,不可避免地出现了膨胀。原本清晰、简洁的代码结构变得复杂和混乱,设计上的不合理之处开始逐渐暴露。这不仅影响了开发团队的工作效率,也对应用的稳定性构成了潜在威胁。

问题造成的影响

代码可读性和可维护性的下降

随着时间的推移和功能的增加,原始代码逐渐变得冗长、复杂,导致代码的可读性和可维护性下降。逻辑的分散和缺乏清晰的结构使开发人员在理解和修改代码时变得困难。这增加了引入错误的风险。

代码可读性和可维护性的下降的具体表现点:

  1. 多层级组件间 Props 传递导致代码难以理解和维护。
  2. 冗余的 state 和不合理的数据结构增加了开发复杂性。
  3. 不一致的编码风格,尤其是在变量命名上,影响了代码的整洁性和团队协作。
  4. 部分组件结构不合理和代码冗余导致了开发效率低下。

考虑的方案处理

  1. 状态管理优化:对于深层组件 Props 传递的问题,采用 Redux 或 useContext 来集中管理状态,减少 Props 逐层传递的复杂性。
  2. 数据结构和状态整理:对现有的 state 进行梳理,优化数据流,调整数据结构,使其更加直观和高效。
  3. 编码风格标准化:与后端团队统一变量命名和编码风格,确保整个项目的风格一致性。
  4. 组件重构与代码抽离:根据业务需求,对组件结构进行调整,识别并抽离通用代码,形成可复用的组件或React Hooks。

最终选择的解决方案

虽然项目中部分页面已引入状态管理工具如Redux或使用React的 useContext,并且确实可以简化多层级Props传递,但在仔细考虑后,认为保持现有的Props传递方式更直观和易于理解。且相较于 Redux 或 useContext , props 的代码复杂度会更低(无需定义各种 reducer)。

所以最终决定将重点放在梳理现有的state,并对其进行整理和优化。通过合并冗余的state变量,消除不必要的重复数据,使用更合理的数据结构,来简化多层级间 props 传递的复杂性以及可读性。同时,确保数据的命名和结构与业务需求保持一致,以便更好地理解和维护代码。以及对复杂组件的结构进行解构并抽离可复用代码。

解决方案的效果

多层级的 Props 传递以及 冗余的 State

先来看下重构前的表现:

image

image

image

重构后: image

image

image

根据业务导向,将关联的数据聚合在一起,并且调整数据结构。同时聚合 State 的 value 和 action, 一定程度的减少 props 的数量。

组件结构的调整以及重复代码的抽取

重构前的表现: image 所有子组件全部处于同级位置,与真实的关系存在差异,且组件结构看起来较混乱。

重构后: image 按照业务关系以及组件之间的真实关系存在组件,并且抽取公共组件至 Common 目录下。

其他优化

新增 LazyLoadComponent 组件来优化组件的渲染。部分组件的隐藏与显示每次都会完全销毁以及重新渲染,考虑到性能,调整为初次未显示时不进行渲染,后续的隐藏以及显示通过 css 属性来控制。