为什么将 Redux 替换为 GraphQL 是个好主意?

近几年来,互联网技术趋向于采用前端 JavaScript 框架来构建更好的网页和移动应用用户体验。这种变化真的很棒🔥,我个人非常喜欢这些框架给我们带来的灵活性。

但是,这种灵活性是否已经过头了呢…

为了真正理解这种情况,我们不妨回顾一下,在 JavaScript 框架诞生之前,应用是如何构建的。

⏳ JavaScript 出现之前的时代…

在最初的几个前端框架(最著名的包括 AngularJS、Backbone 和 Ember)开发之前,我们通常在服务器上渲染模板,然后将完整的 HTML 页面发送到浏览器。当时流行的框架包括:

  • Django(Python)——首次发布于2005年7月21日。
  • Ruby on Rails——首次发布于2005年12月13日。
  • Symphony(PHP)——首次发布于2005年10月22日。

这些框架围绕 MVC(即模型-视图-控制器)应用开发结构的概念展开。模型定义了数据的“形状”,视图是展示数据的模板,控制器则“连接”这两者。

我的意思是,当时也有 JavaScript,但我们讨论的更多是像 jQuery 滑块之类的小工具,以及一些制造完全不必要的弹跳效果的奇特库…

基于这些框架构建的应用存在一些问题,但总体上,一切都运行得相当不错。然后有一天,Ryan Dahl 提出了一个绝妙的想法,开始将 JavaScript 用作不仅仅是制作愚蠢动画的工具。他开发了 Node.js 的第一个版本,使开发者可以在浏览器之外的服务器上使用 JavaScript 编写代码。

  • Node.js——首次发布于2009年5月27日。

突然间,人们开始欣赏 JavaScript 的强大功能和少量代码就能完成大量工作的能力。这启发了其他开发者对 JavaScript 的可能性有了新的认识。人们不仅开始为 Node.js 构建更强大的工具,还开始创建有趣的前端框架。在接下来的几年中,JavaScript 开发开始呈现雪球效应:

  • Express.js(后端)——首次发布于2010年11月16日。
  • Backbone.js(前端)——首次发布于2010年10月12日。
  • AngularJS(前端)——首次发布于2010年10月20日前。
  • Ember.js(前端)——首次发布于2011年12月8日。

这标志着应用开发方式的重大转变。以前由服务器纯粹处理的 MVC 框架分为两个部分——一个服务器处理 MC(模型和控制器)和一个前端客户端使用上述 JavaScript 框架处理视图。在这些早期框架中,他们还在视图中包含了模型和控制器。前端和后端都有双重模型和控制器——现在这听起来像是大量的代码!🙇🏽‍

🤦‍ Facebook 遇到了问题

大家都很高兴。一切都运行良好,一旦你花几个小时来理解它,就会相对容易理解。

然后发生了一些事情…

Facebook 的发展迅速,成为世界上最大的网络应用。可以想象,成为最大的网络应用带来了一些挑战。其中一个最大的头痛问题是:在标题栏显示正确的通知数量。

随着人们在 Facebook 应用中进行操作,这些小的通知应该相应地更新。但这往往不是这样。我不知道你那时是否在使用 Facebook 或者你是否还记得,但这些通知总是出错……问题在于,对于网络应用来说,很难识别应用的一个部分(例如,当你读取一条消息时)的变化,并在另一个区域显示这一变化(例如,将未读通知减少一个)。

这不是世界上最糟糕的事情——通过重新加载页面可以解决——但 Facebook 有超过 1,000 名充满热情的员工,决定是时候做点什么了。因此,他们重新思考了前端框架处理信息的方式,并决定创建他们自己的框架;React。

  • React(前端)——首次发布于2013年3月。

这个新框架擅长渲染 HTML,但也非常基本,并没有太多关于“如何”开发应用的指导。因此,他们还推出了 Flux,最终演变为我们所称的 Redux(重做 Flux)。下面是 2014/2015 年 Flux 网站上的一个视频。该视频试图解释 Flux 和 React。

🍐 …然后事情开始变得糟糕

Redux 的工作方式本质上是将应用的所有动态信息存储在一个 JavaScript 对象中。每当应用的某个部分需要显示一些数据时,它会从服务器请求这些信息,更新单个 JavaScript 对象,然后向用户显示这些数据。通过将所有信息存储在一个地方,应用始终显示正确的信息,无论你在哪里查看。这解决了 Facebook 的通知问题。

所以突然间,有了一个新的框架来构建应用;React Redux 实现。Facebook 解决了他们的问题,而且每个人都过上了幸福的生活…对吗?

✋ 并非如此。

问题在于,人们(包括我自己)开始使用单一对象来存储他们的所有信息——服务器提供的每一条数据。当然,这确保了所有信息都是最新的,但它也带来了三个主要缺点:

  1. 它需要大量额外的代码才能正常工作,这消耗了你所有的时间
  2. 通过将所有代码放在一个地方,你还引入了“陈旧数据”的概念,这意味着你的应用中可能会出现以前状态的不必要数据。
  3. 新开发者的学习曲线极高,随后使得前端网页开发非常难以被新开发者采用。

我们设法将向用户显示数据的相对简单任务,从 2005 年的 MVC 框架的几个简单模板,变成了前端应用的庞大系统,前端的代码比后端多了10倍。例如,我最近开发了一个简单的应用,并使用 WakaTime 来衡量我在编码上花费的时间。这是结果:

  • React Redux 前端仓库——32 小时。
  • Express + Mongoose 后端仓库——4 小时。

你是认真的吗?🤯 我在前端花的时间是后端的8倍。让我们深入了解为什么需要这么多额外代码。以下是我需要遵循的步骤,以便将基本数据获取调用(例如,获取所有用户)添加到我的前端仓库中。

🚧 警告:以下步骤非常技术性,如果你迷失了也不用担心。

  1. 创建显示用户列表的组件(这里没有问题)。
  2. 创建对 API 的 fetch 调用。
  3. 在状态中添加一个新字段。
  4. 添加一个新的动作,该动作将数据更新到状态中。
  5. 添加一个新的 thunk 方法,这个方法执行 fetch 调用然后使用我们的新动作更新状态。
  6. 使用 connect() 将 thunk 函数添加到我们的组件中,这会将其包装在一个 dispatch 函数中。
  7. 再次使用 connect() 从 Redux 状态中提取数据。
  8. 在我的组件的 prop 类型中声明 thunk 函数和提取的数据字段。
  9. 在 componentDidMount() 函数中调用 thunk 方法。
  10. 最后在 DOM 中渲染数据。

天哪… 10个步骤… 回到 Ruby on Rails 的好时光,我所需要做的就是将数据给我的 HTML 模板,然后砰的一声!它会产生相同的结果。我意识到需要改变一些事情。

☝️ 一种新的方法

Redux 非常适合解决保持前端应用同步的问题,但它自己也带来了问题(如前所述)。当你想一想;Redux 究竟给我们带来了多少额外的功能?

本质上,我们重写了整个前端,以解决一些琐碎的问题…

Facebook 也意识到了这一点,并实际上开始研究一种名为 GraphQL 的新技术来帮助解决这个问题。GraphQL 目前是一个热门话题,但我不确定是否真的有人理解为什么它如此酷炫。

GraphQL  像 Redux 那样。再次,Facebook 提供了一个了不起的产品,但未能清楚地表达为什么这个珍贵的产品如此重要;因此我花了最后几分钟给你一些背景。

总之,GraphQL 是一辆车,Redux 是一匹马。

什么?Redux 怎么是马?

我将两者描述为马和汽车的原因是;你绝不会认为马与汽车相似——一个是有四条腿的活生生的动物,另一个是有轮子的机器。然而,它们都试图实现相同的最终目标,即将人带到他们需要去的地方。汽车在街道上行驶,使用燃料,而马是一种雄伟的动物,可以跳过岩石。两者都有不同的优势和用例,但总的来说;汽车会比马更快地把你带到终点。

那么,GraphQL 是什么?

官方文档将 GraphQL 描述为“API 的查询语言”,这非常不清楚。他们所说的查询语言的本质是它实际上用潜在的数百个 HTTP 端点替代了一个 API。由于这项技术还很年轻,文档和支持技术仍有些难以理解;因此,这里也有一个学习曲线。为了帮助理解,这里是一个例子。

GraphQL 将替换诸如以下的端点:

  • GET /users/1234567890
  • POST /cars
  • PUT /example/endpoints

自定义查询替换,这些查询只在你需要时创建。例如:

{  user(id: "1234567890") {    name,    email  }}

将返回:

{  "user": {    "name": "Luke Skywalker",    "email": "**********"  }}

但等一下——自定义查询… 这将花费很长时间来实现。~ 你的想法。

实际上并非如此。原因是;通过只请求你需要的数据,你突然不需要发出那么多服务器请求,这意味着你不需要编写那么多代码来处理这些服务器请求。因此,你最终节省了大量你需要实现的代码的时间。

🤷‍ 但这如何取代 Redux?

另一个很好的问题,谢谢你的提问。简单地说,它不会。然而,它确实做的是鼓励将所有信息存储在 Redux 提供给你的单一对象中。这是因为每个查询都是专门设计来只获取应用的一部分数据——而不是整个应用的数据。将特定于应用的一个部分的信息存储在整个应用的数据源中,是一种反模式(而且根本不合逻辑)。

通过使用 GraphQL,你消除了对 Redux 的依赖,从而去除了大量不必需的代码。

还有一点需要注意的是;Redux 和 GraphQL 可以在一个应用中共存。这很有帮助,因为如果你已经实现了 Redux,你可以慢慢地将 GraphQL 集成到你的 Redux 应用中。

使用 Redux 然后变成一种选择。用它来解决一些琐事并带来所有它的开销和问题,或者用别的东西替换这些任务。

好的,那么你用什么来代替呢?

Redux 是当时解决问题的好方法。然而,自从它问世以来,网页开发产业已经飞速发展,随着这种发展,网络套接字的引入和改进也随之而来。

网络套接字是服务器和客户端之间的开放连接,使服务器能够告诉客户端何时特别更新数据。猜猜怎么着?GraphQL 在名为订阅的功能中直接支持网络套接字。因此,我们可以使用这些订阅来更新我们希望保持同步的应用部分。

主要区别在于;与其让客户端告诉我们需要更新什么(使用 Redux),不如让我们的服务器告诉客户端数据必须更新。这给我们带来了同样的结果。

全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务