首页 > 解决方案 > DRY React:扩展与否。我的团队似乎不同意

问题描述

我在一个 React 项目中工作,我们有自定义样式的表单元素。复选框和单选按钮都呈现为:

  1. 一个隐藏的<input />领域。
  2. A<label>连接到input.
  3. 它基于:checked伪类更改渲染的 SVG 元素。
  4. checkboxa和之间的唯一区别radio是 CSS 使单选按钮看起来是圆形的,而复选框项目是方形的。
  5. 浏览器只负责选择 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。

谁对谁错?

标签: javascriptreactjs

解决方案


在决定共享代码(创建抽象)时,我问自己的问题是

  1. 这个抽象做了什么假设?
  2. 这些假设成立并且用例没有分歧的可能性有多大?如果现在相同的东西在一个月内很可能会有所不同,那么现在共享代码可能不是一个好主意。我通常会对此持相当悲观的态度,因为软件往往会以难以预测的方式出现分歧。
  3. 我从抽象中受益多少?它会显着提高生产力吗?
  4. 如果我最终得到一个不适合的用例,解开这种抽象会有多困难?

不幸的是,从那里并没有真正的神奇公式,但我再次尝试保持相当悲观,并避免在出现危险信号时创建抽象。稍后创建抽象并替换重复代码比删除糟糕的抽象要容易得多。

在你的情况下,我对问题的回答是

  1. 所做的假设是单选和复选框组件在输入类型和图标之外是相同的。
  2. 由于复选框和收音机不同,因此可能存在其他差异似乎很合理。您可能想要一个样式或行为,而不是另一个,这在没有抽象的情况下更容易完成。
  3. 好处是微乎其微的。正如您所说,删除了少量重复。如果两者最终需要以相同的方式进行更改,现在必须在两个地方而不是一个地方进行更新。
  4. 删除抽象并不困难,因为共享代码的数量非常小且简单。

所以在我看来,由糟糕的抽象造成的糟糕情况的风险非常低,但你也不会从中受益太多。我个人倾向于不在这两者之间共享代码,但我也不认为这是正确/错误的情况;对我来说,好处并不能证明它的存在。

几年前来自 React 团队的 Sebastian Markbåge 的演讲确实改变了我对抽象的看法,总的来说让我更加犹豫是否要接触它。


推荐阅读