百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

6 个常见的 React 反模式,正在损害你的代码质量

liuian 2025-05-11 17:04 5 浏览

当我刚开始使用 React 时,一切似乎都很简单 —— 只有几个组件、一些 props 和状态。但随着项目的增长,我开始遇到一些问题。我意识到这些问题其实是伪装成模式的反模式 —— 不是好的那种,而是有害的。在这里,我主要指的是我在许多代码库中看到的代码模式,这些代码是由不同经验水平的开发者编写的,并不一定是真正意义上的“模式”。

1.Props 钻透

问题: Props 钻透发生在你将 props 从顶级组件传递到中间组件,最终到达实际需要它们的组件。当你的组件树很深,且 prop 只在链的末端被一个组件使用时,这会显得尤为成问题。

为什么不好: 这会导致组件紧密耦合,难以重构。如果 prop 的需求发生变化,你可能需要更新从顶层到底层之间的每个组件。整个系统会变得脆弱且难以维护。

想象一个 SearchableList 组件,它通过 List 将 onItemClick 函数传递给 ListItem。每个中间组件都必须处理 props,即使它们实际上并不需要它们。这为了一点点收益增加了大量的复杂性。

代码示例 — 不好的方法:

function SearchableList({ items, onItemClick }) {
  return (
    <div className="searchable-list">
      <List items={items} onItemClick={onItemClick} />
    </div>
  );
}

function List({ items, onItemClick }) {
  return (
    <ul className="list">
      {items.map((item) => (
        <ListItem key={item.id} data={item} onItemClick={onItemClick} />
      ))}
    </ul>
  );
}

function ListItem({ data, onItemClick }) {
  return (
    <li className="list-item" onClick={() => onItemClick(data.id)}>
      {data.name}
    </li>
  );
}

你必须将 onItemClick 从 SearchableList 一路传递到 ListItem,中间的所有组件都包含这个 prop 和函数,但它们什么也不做。

这在人们试图“修复”问题时非常常见,或者他们没有时间去思考影响会有多大。

2.在组件内进行数据转换

问题: 直接在组件的 useEffect 或渲染函数中转换数据,通常感觉是最简单的做法。你获取数据,按需转换,然后设置状态 —— 全部在一个地方完成。

为什么不好: 这会在组件内混合关注点,使其承担多个职责 —— 获取、转换和渲染。这也会使测试变得困难,并限制转换逻辑的可重用性。随着转换变得越来越复杂,这会使组件更难以理解和维护。

考虑一个 UserProfile 组件,它获取用户数据并转换它,例如合并名字和姓氏。将所有这些逻辑放在 useEffect 中意味着每次更改都需要获取和转换 —— 效率不高。

代码示例 — 在组件内转换:

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);
  useEffect(() => {
    fetch(`/api/users/${userId}`)
      .then(response => response.json())
      .then(data => {
        // 在组件内转换数据
        const transformedUser = {
          name: `${data.firstName} ${data.lastName}`,
          age: data.age,
          address: `${data.addressLine1}, ${data.city}, ${data.country}`
        };
        setUser(transformedUser);
      });
  }, [userId]);

  return (
    <div>
      {user && (
        <>
          <p>Name: {user.name}</p>
          <p>Age: {user.age}</p>
          <p>Address: {user.address}</p>
        </>
      )}
    </div>
  );
}

这个示例展示了如何在 useEffect 中直接数据获取和转换,导致组件紧密耦合,使测试变得困难。

3.在视图中包含复杂逻辑

问题: 你是否曾经因为“只是一小段”而直接在组件中包含一些业务逻辑?但很快组件就充满了条件语句和计算。

为什么不好: 组件应该专注于呈现 UI,而不是实现业务规则。你在组件中放入的逻辑越多,重用它们就越困难。这会导致组件臃肿,难以测试和理解。

想象一个组件,它不仅显示订单详情,还计算折扣、运费和预估税 —— 这种逻辑如果放在单独的服务函数或钩子中更具可重用性。

4.缺乏测试

问题: 跳过测试可能感觉节省时间,尤其是在截止日期时。但 React 组件通常处理复杂功能 —— 如管理表单状态或 API 调用 —— 这可能导致难以诊断的错误。

为什么不好: 没有适当的单元或集成测试,当重构或添加功能时,没有安全网来捕获错误。每次更改都成为一项冒险,你会发现自己做了很多手动测试,但仍无法覆盖所有场景。

我还记得在某个功能中,购物车在某些边缘情况下未能更新。适当的单元测试本可以在问题进入生产环境之前捕获这些问题。

5.重复代码

问题: 复制粘贴一段代码通常是 easiest solution —— 你已经写过了,为什么不直接重用呢?问题在于,每个重复实例都是维护负担。

为什么不好: 当需求变化时,你需要更新每个重复实例,遗漏其中一个可能会导致错误和不一致。这是确保你的逻辑保持集中且易于修改的问题。

想象一个 formatDate() 函数,它出现在多个组件中,因为你每次需要时都粘贴了它。当格式要求变化时,这会变成一项搜索并希望你找到了所有实例的任务。

代码示例 — 重复代码:

function AdminList(props) {
  const filteredUsers = props.users.filter(user => user.isAdmin);
  return <List items={filteredUsers} />;
}

function ActiveList(props) {
  const filteredUsers = props.users.filter(user => user.isActive);
  return <List items={filteredUsers} />;
}

这个示例展示了如何在不同组件中过滤用户逻辑,导致代码重复。

6.责任过多的长组件

问题: 你可能会想到一个像 OrderContainer 这样的组件,它管理与订单相关的所有内容 —— 验证、错误处理、获取数据和渲染 UI。

为什么不好: 组件应该遵循单一职责原则(SRP)。当它们有太多职责时,它们会变得复杂且难以调试、理解和扩展。如果某部分逻辑依赖于另一部分,它们也会非常难以测试。

在一个项目中,我有一个表单组件,它处理验证、提交、错误显示,甚至管理全局状态。将其拆分为更小的组件并提取不同任务的钩子,使代码更易于处理。

原文:
https://training.shikshatech.in/6-common-react-anti-patterns-that-are-hurting-your-code-quality/

相关推荐

HR必备Excel函数:4个与日期相关的计算函数。

提到日期函数,很多人首先会想到“today”,它可以显示当天的日期,并且每次打开表格时都会自动更新。但是,对于前天、昨天、明天和后天的日期,就不能用yesterday或者tomorrow等这些英文了,...

这篇文章有点长,但可以让你十分钟玩转Excel的时间函数

日期与时间函数——TODAY、NOW、YEAR、MONTH、DAY!如何用WORKDAY函数查询距离某天的第20个工作日是哪一天?如何用NETWORKDAYS函数查询员工工作了多少个工作日?如何用WE...

Excel2020年日历套装,表格设计,农历显示,查阅套打轻松应用

Hello大家好,我是帮帮。今天跟大家分享一组Excel2020年日历套装,表格设计,自带农历控件,查阅套打轻松应用。有个好消息!为了方便大家更快的掌握技巧,寻找捷径。请大家点击文章末尾的“了解更多”...

巧用NETWORKDAYS函数计算两个日期之间工作日的天数

带有日期的单元格是我们日常使用EXCEL的时候经常见到的,有的时候我们需要求出两个日期之间间隔的天数,可以直接用结束日期减去开始日期即可,这是个非常简单的减法公式。不过这个单纯的减法公式会默认去掉开始...

Excel按工作日、休息日进行汇总

1、按周六日/其它时间汇总为了区分一周的周六日和其它时间,可以使用WEEKDAY函数,把WEEKDAY函数的第2个参数指定为2,如WEEKDAY(A3,2),则周一返回1,周二返回2,…,周六返回...

如何计算每月应出勤天数,如有法定假期和调休,如何计算

本文介绍如何计算每月的应出勤天数。第一部分介绍正常双休制下计算应出勤天数;第二部份介绍当月有法定假期和调休的情况下计算应出勤天数。一、计算正常双休制的应出勤天数如下图所示,要求计算各员工2021年3月...

《Excel一键生成工作日历:让会议排期更轻松!》

每当需要安排会议时,总要翻看日历确认工作日,再逐个标注会议时间,既耗时又容易出错。今天教大家用Excel快速生成工作日历表,让会议排期变得简单高效!一、快速生成日历框架创建基础日期:在A1单元格输入月...

如何计算指定日期区间内,有多少工作日和休息日?

大家好,今天咱们要解决的问题是如何计算给定的一段日期内,正常工作日有多少天,放假时间有多少天?比如咱们要计算2025年3月份工作日一共有多少天,又有多少天放假,如下图所示:通过肉眼我们可以数清楚,20...

如何如何在表格中自动突出显示双休日?

现在不少人喜欢用Excel来制作备忘录或安排工作事项。在表格中输入日期后,可以使用条件格式突出显示双休日,避免在休息日安排了工作。具体方法是这样的:第1步:选择要设置条件格式的日期单元格区域;在“开始...

excel函数技巧:networkdays.intl判断节假日

如图,想知道6月的每一天是否是节假日,公式如下:=NETWORKDAYS.INTL(A2,A2,1,$E$2:$E$28)这个函数既可以判断当前日期(一参=二参)是否是周末及工作日(三参、四参)还可得...

仅需3步,让考勤表根据实际休息日,自动地填充颜色

Hello,大家好,之前跟大家分享了我们如何让考勤表根据单休与双休自动的填充颜色,最近有粉丝问到:能不能让考勤表根据实际的休息日自动的填充颜色呢?可以是可以,只不过因为牵扯到假期调休,我们每年的休息日...

5步搞定动态考勤表!标记节假日、调休日?Excel自动变色!

今天教你用「动态考勤表」一招解决所有问题!只需输入月份,自动变色、自动更新节假日,从此告别加班,效率翻倍!动态考勤表的优势:自动变色:节假日、双休日一键标记,颜色分明。一表多用:修改月份即可...

一起用python做个炫酷音乐播放器,想听啥随便搜

前言前段时间写的Python自制一款炫酷音乐播放器,有不少小伙伴私信我,对播放器提了不少改进建议,让我完善播放器的功能。今天音乐播放器2.0版本完成了,大家一起来看看是如何用python自制一款炫酷的...

用Python做个“冰墩墩雪容融”桌面部件(好玩又有趣)

桌面太单调?今天就带大家,一起用Python的PyQt5开发一个有趣的自定义桌面动画挂件,看看实现的动画挂件效果!下面,我们开始介绍这个自定义桌面动画挂件的制作过程。一、核心功能设计实现将动态图gif...

Python串口调试助手源码分享

以下是一个基于Python和PyQt5实现的串口调试助手示例,包含核心功能实现代码:pythonimportsysimportserialfromPyQt5.QtCoreimportQTim...