javascript - DRY React:扩展与否。我的团队似乎不同意
问题描述
我在一个 React 项目中工作,我们有自定义样式的表单元素。复选框和单选按钮都呈现为:
- 一个隐藏的
<input />
领域。 - A
<label>
连接到input
. - 它基于
:checked
伪类更改渲染的 SVG 元素。 checkbox
a和之间的唯一区别radio
是 CSS 使单选按钮看起来是圆形的,而复选框项目是方形的。- 浏览器只负责选择 1 个单选项目。
现在,这个组件的基本渲染 HTML 是:
<input type={type} id={someid} />,
<label htmlFor={someid}>
<div className="icon">
{type === 'checkbox' && <CheckMark />}
{type === 'radio' && <CircleMark />}
</div>
{label}
</label>
所以我设置了一个 radio.js React 文件。而我的 checkbox.js React 文件只是扩展了收音机:
export default class Checkbox extends PureComponent {
render() {
return <Radio {...this.props} type="checkbox" />;
}
}
附加的 CSS 文件也是如此。他们使用 SASS 工作,所以我的 checkbox.sass 基本上可以:
@extend .input__radio;
没有代码重复。一切皆好。
现在我的同事已经复制了整个 radio.js 和 radio.scss 文件,并复制了 checkbox.js 和 checkbox.scss 的代码。
我的团队 100% 同意他的观点,因为:“他们是不同的!”
结果是 72 行重复的 JS 和 80 行重复的 CSS。
谁对谁错?
解决方案
在决定共享代码(创建抽象)时,我问自己的问题是
- 这个抽象做了什么假设?
- 这些假设成立并且用例没有分歧的可能性有多大?如果现在相同的东西在一个月内很可能会有所不同,那么现在共享代码可能不是一个好主意。我通常会对此持相当悲观的态度,因为软件往往会以难以预测的方式出现分歧。
- 我从抽象中受益多少?它会显着提高生产力吗?
- 如果我最终得到一个不适合的用例,解开这种抽象会有多困难?
不幸的是,从那里并没有真正的神奇公式,但我再次尝试保持相当悲观,并避免在出现危险信号时创建抽象。稍后创建抽象并替换重复代码比删除糟糕的抽象要容易得多。
在你的情况下,我对问题的回答是
- 所做的假设是单选和复选框组件在输入类型和图标之外是相同的。
- 由于复选框和收音机不同,因此可能存在其他差异似乎很合理。您可能想要一个样式或行为,而不是另一个,这在没有抽象的情况下更容易完成。
- 好处是微乎其微的。正如您所说,删除了少量重复。如果两者最终需要以相同的方式进行更改,现在必须在两个地方而不是一个地方进行更新。
- 删除抽象并不困难,因为共享代码的数量非常小且简单。
所以在我看来,由糟糕的抽象造成的糟糕情况的风险非常低,但你也不会从中受益太多。我个人倾向于不在这两者之间共享代码,但我也不认为这是正确/错误的情况;对我来说,好处并不能证明它的存在。
几年前来自 React 团队的 Sebastian Markbåge 的演讲确实改变了我对抽象的看法,总的来说让我更加犹豫是否要接触它。
推荐阅读
- python - 正则表达式。是否可以相对于另一个元素设置条件但不匹配它
- c# - NuGet 版本冲突
- python - 如何使用 python 从 pandas 数据框中排除某些列
- javascript - 如果重复 3 次,则删除数据(Jquery)
- python - 无法在 python tkinter 中导入 ttk
- sequelize.js - 在express js中使用sequelize如何从关联表中返回多条记录
- c - /tmp/pdG7WaW1iq.c:227:7:错误:“CreateListNode”的类型冲突 | /tmp/pdG7WaW1iq.c:171:19:错误:重新定义“新”
- html - 如何仅将引导父类 .text-md-left 覆盖到标签
- html - 插入 yml 的样式 html 元素不起作用
- javascript - Svelte 对数组操作的反应性