一个运行一年的 React 项目中的遗憾
由 Mux 赞助的 DEV 全球展示挑战赛:展示你的项目!
JavaScript 生态系统已经变得令人担忧。NPM 上有超过 60 万个软件包可供选择,而且每天新增超过 600 个,“最佳实践”正以惊人的速度被新兴的热门技术所挑战和取代。
在启动新项目时,人们自然会避免盲目尝试所有新事物,而是选择真正需要的。我们当初启动项目时就是这么做的。
这是我们从一开始就后悔做了或没做的事:
1. 未使用选择器
我们当初就不应该在没有选择器的情况下直接操作 Redux Store 。最初的理由很简单:如果你需要专门的方法来从 Store 中提取数据,那就说明你的 Store 太复杂了。应该简化它;隐藏这种复杂性只会让它更加恶化。
但我们忽略了选择器至关重要的另一个原因(我觉得这一点没有得到足够的重视):重构。接受现实吧——你现在设计的商店和一年后你使用的商店肯定不一样。需求会变,设计会变,新功能会添加,功能会被移除;软件在不断发展,你的商店也需要随之发展。
事实证明,使用一个明确定义数据存储所需内容的单一接口,可以简化重构过程。视图(甚至包括容器组件)无需了解数据存储的具体结构,它们只需关心接收到哪些数据即可。
此外,编写单元测试也变得轻而易举。只要选择器返回相同的数据,你就可以随意更改数据存储。
2. 未为 Recompose HOC 链编写 PropTypes
我们大量使用了 Recompose。我们的展示型组件被包裹在一个由 Recompose 高阶组件 (HOC) 组成的链中,这些高阶组件最终构建出容器组件。最初它们非常简单,只有一个 Redux connect 和几个 withProps 和 withHandlers。
HOC 链看起来很棒,数据像瀑布一样向下流动,但当你移动组件时会发生什么呢?很容易搞不清数据流向。你可能在一个 HOC 中移除或更改了一个属性,却没意识到下面几个组件中的某个 HOC 依赖于它。
一个简单的解决方法是为每个高阶组件 (HOC)定义清晰的PropTypes (或者使用类似 Flow 或 TypeScript 的类型系统)。为组件编写 PropTypes 很容易,大多数代码检查工具也会检查这一点,但为 Recompose HOC 编写 PropTypes 就没那么直观了,而且据我所知,目前还没有代码检查规则来检查这一点。目前还没有明确的最佳实践。这只能成为项目约定,并且需要在同行代码审查中强制执行。
3. 将过多的控制权让渡给图书馆
“我们只是想快速搭建一个最小可行产品(MVP)来启动项目。我们不需要花太多时间在花哨的设计上,就用一个流行的组件库吧”——大多数项目都是这样开始的,但不知不觉中,你就要服务成千上万的用户了,猜猜会发生什么?精美的设计就成了必不可少的东西。
我们最初使用Material UI开发这个项目,它非常棒。它包含了你所需的所有组件,拥有炫酷的动画效果,而且易于构建。然而,随着项目规模的扩大,我们的“MVP”阶段已经无法满足需求。我们需要一些新的复杂功能,而这些功能无法用简单的 Material UI 组件来实现。使用内联样式带来的性能损失虽然不大,但累积起来却不容忽视。
之后,我们使用的 Material UI 版本停止维护了。新版本将进行重写,并带来急需的性能提升。GitHub 上所有与旧版 Material UI 相关的 issue都已关闭。
因此,我们有一个相对较大的应用程序,它仍然使用一个老旧的库,存在性能问题,而且无法更新到最新版本的 React。
我们该怎么办?要么停止所有工作,升级到新版本。但是新版本中被移除的那些组件怎么办?找新的组件来替代它们,然后重构代码使其兼容新组件?或者干脆放弃 Material UI,为所有组件编写自定义组件?
我们负担不起这两项措施。我们计划分阶段重构代码,移除较大的依赖项,一旦代码足够简洁,我们就会升级到新版本(前提是新版本已经结束测试阶段)。
4. 未使用 CSS-in-JS
正如我所说,我们一开始就使用了 Material UI,这已经足够满足我们的需求了。我们很少需要自定义任何组件,即使需要,我们也遵循官方建议使用内联样式(这是因为 Material UI 内部就使用了内联样式)。
此外,我提倡 React 提出的水平关注点分离,我不喜欢将一个组件拆分成多个文件(单独的 CSS 和 JS 文件)。
我们一开始没有使用 CSS-in-JS 的原因是,当时我们并不需要它,而且即使使用内联样式增加了一些性能开销,也完全被 Material UI 的强大功能所掩盖。此外,CSS-in-JS 社区内部也存在一些相互冲突的实现方式,而且当时还没有出现一个公认的标准库(现在也没有)。
现在我们正在逐步放弃 Material UI,更多地采用手动构建 UI,这个问题变得越来越突出。目前我们仍然使用 CSS,因为大家都习惯了这种方式,但我们正在逐步将每个组件的 CSS 代码拆分,以便将来顺利迁移到 CSS-in-JS。
结语
这份清单并非旨在囊括启动 React 项目时需要注意的所有事项。我相信网上已经有很多相关的资料。这里列出的是一些我很少看到,但却给我们带来最大麻烦的问题。
文章来源:https://dev.to/squgeim/regrets-in-a-1-year-old-react-project-4j7j