为了账号安全,请及时绑定邮箱和手机立即绑定

你的React应用并不完美——原因在这里

如何让你的同事们也喜欢上你的React项目。

照片由 OSPAN ALI 拍摄,来自 Unsplash (经由)

自从2013年5月首次公开发布以来,React 提供了以更模块化的方式构建 web 应用程序的工具。然而,这个著名的库并没有提供太多关于如何结构化代码的指导,这带来了极大的灵活性,无论好坏。

提前道歉,你是否遇到过这样的情况:你的React组件看起来像下面这个?

const YourComponent = ({ props1, ..., props7 }: MyComponentProps) => {  
  const { state1, setState1 } = useState<...>(...)  
  const { state2, setState2 } = useState<...>(...)  
  const { state3, setState3 } = useState<...>(...)  
  // 这里有更多的状态...  
  // ...  

  useEffect(() => {  
    // 负责获取和映射处理将在 JSX 部分使用的数据的二十行(或更多)代码。  
  },[/* 需要监视的几个变量的列表。 */])  

  // 处理数据和响应用户操作的指令。  
  // ...  
  // 另一个 useEffect() 是否会让我们更加混乱?  
  // ...  
  // 我们现在在第几行?可能是第 105 行了吗?  
  // ...  
  // 生成 JSX 代码的辅助函数在这里...  
  // ...  
  // 第 145 行,唉...  
  // ...  
  return (  
    <div>  
      <...  
         (...)    
         三十多行(或更多)的 JSX...  
         (...)  
      ...>  
    </div>  
  )  
}

如果可以的话,咱们想一下怎么改进事情吧。

我要试着向你推销一样东西——这需要你花一些时间和精力,但(希望)能帮你和你的同事们省下调试那些过度耦合承担了太多职责的代码所花费的好几个小时。

我们可以创建一个来表示上面React组件的示意图

你的 React 组件可能看起来是这样的……

如你所见,我们的 React 组件承担了 五种不同的任务

  1. 管理 React 的状态
  2. 处理用户的操作
  3. 从 API 接口获取数据,捕获异常以及管理加载阶段
  4. 转换和映射化不同来源的数据
  5. 使用 JSX 定义 UI 和 DOM

这确实很多,对吧?除了这些问题(经常让人摸不着头脑),逻辑也难以测试和扩展。此外,这些应用在数据流动上也显得不够一致。信息在应用里乱七八糟的,让人更摸不着头脑。

所以,,让我们试着通过分离关注点来解决这个问题。这会是个什么样的方案呢?

职责分离的概念有助于让你的 React 应用更易于阅读、测试和维护。你的同事会喜欢这个做法 ❤️。

让我们来了解上面的图中引入的这些实体的责任。从左到右:

顾客
  • 客户端负责对接外部数据源,通常通过API。它们暴露可由控制器直接处理的类型化的结构。
  • 它们与React生命周期无关,这意味着它们根本不依赖于React实体。它们是简单的类(或函数),其中包含API信息。
  • 它们处理API错误,并将可由应用程序处理的错误重新抛出(通常通过错误回退机制)。
有状态的控制器

什么是“有状态的控制器”?在某些上下文中,这可能不那么清晰,这里指的是那些能够维护和使用内部状态信息的控制器。

  • 有状态控制器 负责处理 React 状态

  • 它们向 视图组件 暴露 数据接口,并且暴露的数据可以直接在 JSX 代码中使用,这种机制可以称为 数据填充

  • 有状态控制器还暴露 回调函数,允许用户修改状态并触发 API 调用。

  • 有状态控制器可以通过关联 React 钩子React 上下文 构建。React 钩子能够轻松地 连接控制器与视图组件,而 React 上下文则使状态 全局化。这样,你可以轻松连接任何视图组件和任何有状态控制器,确保 状态在各个组件间共享

  • 有状态控制器不涉及任何 JSX 代码,这使得测试变得更加容易,因为输出是一系列结构化的数据和回调函数。

有状态和无状态的控制器值得单独写一篇文章。如果你有兴趣,请在评论区留言,告诉我你是否想更深入地探讨这些概念的细节。

数据映射和转换
  • 在某些情况下,通过API获取的数据(或发送到API的数据)需要进行复杂的转换。这些转换可以被提取到专门的模块中以提高可测试性。
  • 数据映射器和转换器与React的生命周期是分离的。
视图部件
  • 视图组件是简单的视图组件,它们连接到控制器并将数据注入到JSX中。
  • 它们不处理、转换或管理数据,而是将这些任务委托给控制器。
  • 它们不再直接使用props,因为它们通过消费钩子从控制器获取数据,这样可以明确数据流并确保数据的一致性。
  • 它们不处理状态。
  • 它们可以通过快照或基本的Jest断言轻松测试。

用这种方法,props传递、callback hell 和高认知负担(甚至像 Redux 🎉 一样)这些问题都将一去不复返。

我们到了。这篇文章旨在给你一个简短的介绍,介绍如何改进你的React应用程序。如果你对某些特定概念想了解更多并希望看到更多具体示例,我很乐意写更多相关文章。请在评论中留下你的请求和反馈。

谢谢阅读!

提升编码水平

感谢你加入我们社区!在你离开之前:

🔔 关注我们哦:Twitter | LinkedIn | Newsletter

🚀👉 加入 Level Up 人才社群,小伙伴们!找到一份超棒的工作

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消