React追求建立更好的网站

66 阅读8分钟

我从2015年开始构建React应用程序。从那时起,React对我的开发来说是最大的一次生产力提升。React基于状态渲染UI的声明式模型极大地简化了我对构建网络UI的思考方式。它也给了我一个思考状态的好方法,比我之前用Angular.js和Backbone所做的要领先很多。

React的口号是:

一个用于构建用户界面的JavaScript库

React在这方面做得很好,它给你提供了它开创的声明式组件模型。如果不管理一些状态,你就无法构建一个用户界面(combobox菜单是open 还是closed ?)。这就是为什么React组件状态管理。

诀窍在于,网络应用有很多东西比本地组件状态更重要。事实上,在典型的React应用中,绝大多数加载的 "状态 "根本不是状态,而是来自服务器的状态缓存(它可能是从数据库等持久层得到的)。 虽然React一直给我们提供了一个管理状态的好方法,但它不能掩盖这样一个事实:我们所管理的大部分状态实际上是一个缓存,并受到缓存问题的影响。

正如Phil Karlton的名言所说。

计算机科学中只有两件难事:缓存失效和事物命名

在很多方面这都是一个笑话,但缓存失效绝对是一个具有挑战性的问题。而到目前为止,React还没有为我们提供任何管理这个问题的开箱即用的东西,这一点可以从围绕React建立的无数库和工具中得到证明。无论你使用的是Redux(工具包)、MobX、Apollo、React Query、SWR,还是其他什么工具,你之所以伸手去拿这些工具,是因为在Web开发中存在一个共同的、共享的问题,而React并没有一个内置的答案。

网络鸿沟的管理

什么是网络鸿沟?

这就是我所说的网络鸿沟的意思。

Excalidraw diagram showing a box labeled client and a box labeled server with the words "Network Chasm" between them

作为网络开发者,我们可以编写在客户端(浏览器)和服务器上运行的代码。我们对网络没有任何控制权。这就是为什么我们首先要考虑缓存的问题。当我们的React组件在用户选择玉米卷时重新显示🌮,我们需要同步访问该特定玉米卷的可用选项🤤。所以我们通过网络发出HTTP请求,并通过React状态(或一些库)将这些值存储在内存缓存中,以便我们重新渲染时可用。

你知道大大小小的应用程序中出现错误的头号原因吗?

代码

这个网络鸿沟是大量代码的来源。把它弄好是非常困难的,但我们正在构建网络应用,所以我们必须尝试。因此,利用JavaScript的力量、现代的fetch API和一些方便快捷的库,我们通过HTTP在网络鸿沟上发射了一个抓钩,以获取来自后端的数据。

Similar diagram as above with a box above "Client" that says "SPA" and an arrow from that over the network chasm pointing to a box that says "Node/Rails/PHP/Java/.Net". The row is labeled "Client-side apps"

对于数据获取,你必须知道要获取什么数据,而这往往是一个具有挑战性的问题,因为我们喜欢将数据获取与需要数据的代码放在一起(通过这种方式可以大大减少错误/误差/数据过度获取)。这就产生了一个不幸的副作用,即在组件渲染之前无法获取数据。

再加上我们希望实现代码分割以使我们的应用程序加载得更快,现在你不仅要等待组件的渲染,而且一旦它开始渲染,你还必须获取进行获取的代码。这导致了网络瀑布(我们都知道瀑布的危险)。

不幸的是,数据获取本身并不能解决这个问题。事实上,即使是React Suspense for Data fetching也无法解决这个问题。Suspense将取代许多数据获取库,能够从组件中获取数据(如果还没有缓存,就会触发数据获取,这就是所谓的获取),但如果你想避免瀑布效应,你必须在这些组件的代码被渲染之前开始获取数据。

尽快获取

这就是为什么我对React Router将解决这个问题感到非常兴奋,因为它将我喜欢的Remix的大部分内容带入了React Router。Ryan在他的帖子Remixing React Router中解释了这一点。利用布局嵌套路由和loaders (获取数据)和actions(突变数据)的力量,你可以将数据获取与组件解耦,但仍能从colocation中获益良多。在这种情况下,获取的代码可能不在组件,但由于嵌套布局路由的性质,它非常接近。

有了这些功能,我们从 "我必须渲染才能知道数据需求 "变成了 "我从URL中知道数据需求"。

除此之外,React Router现在为你管理了一些网络鸿沟,这意味着你有更少的自己的代码需要担心加载/错误状态。这也意味着React Router可以为你处理缓存的重新验证。哦,还有表单重新提交和竞赛条件(UI开发中的一些更具挑战性的问题)。而构建优秀的用户体验(如乐观的UI模式)从未如此简单。这有效地缩小了你的网络鸿沟。

Similar diagram as before except now the SPA box extends slightly further over the network chasm and the row is labeled "Remixed Router apps"

我们能做得更好吗?

在React Router中拥有这些功能,对于任何希望简化代码和加快应用速度的人来说,都将是一个巨大的好处。React Router将是任何使用React Suspense获取数据的人的最好朋友(除非你有Meta那样的基础设施/编译器/路由器,我想)。

但我们可以做得更好。即使你提前开始从浏览器中获取数据,你的用户仍然需要等待最初的JavaScript包出现并执行,才能看到任何东西。有了React Router帮助你管理数据的加载和变异,你可以删除大量的状态(缓存)管理代码,但它仍然都在浏览器中。最重要的是,因为我们需要在获得需要获取的数据的代码之前进行获取,这意味着代码不再是代码分割的了。

如果我们能把所有的代码从浏览器中移到服务器上,那不是很好吗?当你需要与数据库对话或遇到需要你的私钥的API时,都要写一个无服务器函数,这不是很烦吗?这些都是React服务器组件承诺为我们做的事情,我们绝对可以期待数据加载,但他们没有为突变做任何事情,如果能把这些代码从浏览器中移出,那就很酷了(而且不必等待它发布)。

进入舞台右侧。混淆💿

要想让你的应用真正达到一个新的水平,你需要对你的应用进行服务器渲染。最好的方法是使用Remix。Remix为你完成了跨越网络边界的桥梁,你甚至不需要考虑这个问题。你把你所有的数据获取和数据突变的代码移到传统的 "Remix路由模块 "的导出函数中,所有的代码都留在服务器上,Remix为你处理整个网络鸿沟。

Similar to the diagrams before with the addition of a "Backend for frontend" row that shows Remix spanning over the client and network boundary into the Server and an arrow pointing to "Rails/PHP/Java/.Net"

现在你的应用程序真的可以飞起来了⚡因为用户不再需要等待JavaScript的加载。应用程序就在那里,并为他们准备好了(由于渐进式增强,所有的链接和表格都可以在后台下载JavaScript时工作)。

还有,因为现在你可以编写在服务器上运行的代码,你不必再担心直接调用数据库或用私钥敲击API。你的加载器和动作只在服务器上运行,所以它们可以做任何你需要的事情。这是很好的DX改进!

你的整个应用程序

Remix为您提供了服务器的力量,这意味着如果您需要,它实际上可以处理您的整个应用程序。不是每个人都想这样做,但因为你有一个可以直接与数据库和第三方服务对话的后端,你可以使你的应用程序结构看起来更像这样。

Similar to the diagrams before with the addition of a "Full Stack" row that shows Remix spanning over the entire client, network chasm, and server

最酷的是,无论你是否使用100%的Remix,你都可以通过使用Remix获得完全管理网络鸿沟的所有好处,所以如果你对现有的后端很满意,你当然可以坚持使用。

总结

React的口号是:

一个用于构建用户界面的JavaScript库

而且它在这方面做得非常好。React从来没有承诺过 "网络鸿沟管理",但每个网络应用都需要它。有了Remix管理网络鸿沟,我们终于有了React的阴阳之分。有了一个伟大的渲染库和一个超级网络鸿沟管理器,你可以建立更好、更快的网络应用,减少错误,简化代码,增加乐趣。

就个人而言,这让我爱上了用Remix构建网络应用。你今天看到的这个网站就是用Remix重写的结果。当我开始的时候,我不知道它将成为多么酷的东西。Remix使这一切成为可能,因为当我完成了基本功能后,我意识到我有时间和能力去做更多的事情(在这里阅读更多关于我的网站重写)。 Remix让我觉得我可以对我的有趣的想法说 "是",这真的很令人振奋。

我希望这能帮助你追求建立更好的网站。保持冷静 😎