“脱水”和“再水合”在 Fluxible 中代表什么?

IT技术 node.js reactjs fluxible
2021-05-16 00:12:24

我正在开发一个可以使用fluxible 的最小应用程序。几乎所有事情似乎都很清楚,但有一件事:脱水和再水化状态的概念。

我知道这是在客户端和服务器之间同步存储所需要的,但我不知道为什么。这条线对我来说很不清楚:

 var exposed = 'window.App=' + serialize(app.dehydrate(context)) + ';';

在 server.js ( https://github.com/yahoo/fluxible/tree/master/examples/react-router )

如果您能用“更简单的词”告诉我它的意思,我将不胜感激。

3个回答

上面的答案很好,但我认为我们仍然可以用比萨更好地解释这个比喻想想回到未来 2 中的这个场景:

回到未来 2 披萨水化器

在这个场景中有两个关键的组成部分:脱水的必胜客披萨Black & Decker hydrator暂时忽略我们还需要一个脱水器来完成这个比喻。

脱水比萨饼是代表完整比萨饼所需的一切,但正如包装纸告诉我们的那样,“除非完全再水化,否则不要食用”。由服务器渲染的脱水披萨看起来很好吃,但实际上并没有完全吸引人。

您的应用程序是 McFly 奶奶的补水器、比萨饼和比萨饼盒说明。奶奶 McFly 是浏览器当用户请求“半意大利辣香肠/半青椒”比萨页面时,后端发送脱水比萨和 Black & Decker 水化器。麦克弗莱奶奶(浏览器)仔细阅读了所有说明,并为用户将比萨饼加水。这是一件非常好的事情,因为用户是个白痴,不知道也不关心脱水比萨饼和脱水比萨饼之间的区别,就像小马蒂一样:

Marty Jr.:(os)奶奶,你能把[脱水披萨]塞进我嘴里吗?(笑)

马蒂:(os)你不聪明!

到目前为止一切顺利,对吧?到目前为止的好处:

  • 用户在第一个请求时获得整个(脱水)比萨饼和水化器,而不是仅仅获得水化器并且必须拨打(网络服务 xhr)调用来订购比萨饼
  • 网络爬虫是特别愚蠢的用户,他们通过查看冷冻比萨获得他们需要的一切,并且不需要 McFly 奶奶来阅读说明并通过给比萨加水来使比萨具有交互性

但是等等,还有更多!用户抓起一两片,然后跑掉,留下剩下的披萨。发生这种情况时,McFly 奶奶从披萨盒说明中知道要保存修改后的披萨状态。她(客户端)将其放入脱水器(未显示)并将其送回橱柜(服务器)。如果用户回来吃完他们的半意大利辣香肠/半胡椒比萨,整个脱水比萨/水化器/奶奶的过程将再次发生,它会一如既往地新鲜,加上他们所做的改变。

我们来复习:

  • 脱水是提取应用程序的当前状态并将其序列化为对象。这可以在服务器端或客户端完成。
  • 再水化是解释状态对象(通过脱水创建)并将应用程序渲染成美味的交互式比萨饼。
  • 任一方向传递脱水状态对象都很有用:从服务器到客户端,或从客户端到服务器。

结束!除了不是真的。

仍然有一个秘密魔法部分可以让这个比喻起作用,那就是每当我们给比萨加水时,我们实际上保持脱水比萨完整所以我们最终得到了脱水比萨饼和脱水比萨饼,然后我们根据需要在幕后同步它们。在 Flux 的情况下,这是通过许多 Stores 组成你的应用程序发生的。在 Redux 中,您只有一个顶级 Store,这可能更容易理解。

在 Fluxible 的上下文中,使您的应用程序脱水意味着其状态提取到一个对象中。再水化你的应用程序是使用同一个对象在你的应用程序中重新注入状态。表示应用程序状态的对象应该是可序列化的,以便通过网络发送。

假设我想在服务器上预渲染我的应用程序,将 html 提供给客户端,然后在客户端重新渲染我的应用程序。如果我的应用程序仅包含静态数据,这将是微不足道的。但是,我的应用程序是有状态的:它在初始渲染之前从我的 API 中检索数据并存储它。通过在服务器上提取我的应用程序的状态,将它与 HTML 一起发送,然后将其重新注入客户端,我避免向我的 API 发出两次请求。

脱水是序列化的另一个词,再水化意味着反序列化。

膨胀 == (re)hydrating == 反序列化

因此,这行代码序列化了路由器的状态并将对象分配给可从客户端访问的 window.app

更新

如何使用序列化的示例:

假设我们有一个用户对象,并希望在请求之间保留当前登录用户的引用。我们可以通过简单地获取用户的 id 并将其保存到会话中来序列化用户。那将是用户对象的序列化或脱水。为了水合或反序列化,我们只需从会话中获取 id,在数据库中找到我们的用户并再次填写用户对象。这里的目的是保持尽可能低的内存占用。

在fluxible的一个例子中,脱水函数简单地返回当前状态名称,水合物函数将状态名称作为参数并将其设置为当前状态。我认为完整的状态对象在客户端和服务器上都是可用的。因此,由于您不需要发送整个州,因此您只需发送州的名称。脱水的功能很简单

State.dehydrate = function(){
    return this.currentStateName;
}