React Simple Global Entity Cache instead of Flux/React/etc



我正在写一个有点"有趣"的Scala/Scala.js项目。

在我的服务器上,我有由uuid-s 引用的实体 (在参考文献中)。

为了"好玩",我不想使用flux/redux架构,但仍然在客户端上使用React(使用ScalaJS-React)。

我试图做的是拥有一个简单的缓存,例如:

  • 当 ReactUserDisplayComponent想要显示带有uuid=0003EntityUser
  • 然后render()方法调用Cache(作为prop传入)
  • 假设这是UserDisplayComponent第一次要求这个特定的User(带有uuid=0003),而Cache还没有它
  • 然后Cache会创建一个AjaxCall,从服务器获取User
  • AjaxCall返回时,Cache触发器re-render
  • 但是!现在,当组件从Cache请求User时,它会立即从Cache获取UserEntity,并且不会触发AjaxCall

我想实现的方式如下:

  • 我开始render()
  • render()里面的"东西"要求Cache提供各种Entities
  • Cache返回LoadingEntity本身。
  • 在渲染结束时,Cache将所有AjaxRequest-s 发送到服务器并等待所有 -s 返回
  • 一旦所有AjaxRequests都返回了(为了简单起见,我们假设它们返回了),Cache触发了一个"re-render()",现在之前请求的所有实体都由Cache立即提供。
  • 当然,新到达的Entity-s 可能会触发render()获取更多Entity-s,例如,如果我加载一个例如case class UserList(ul: List[Ref[User]])类型的Entity。 但是我们现在不要担心这个。

问题:

1)如果我以这种方式进行状态处理,我真的做错了什么吗?

2)是否有已经存在的解决方案?

我环顾四周,但一切都是FLUX/REDUX等......沿着这些思路... - 我想避免这样做:

  • "好玩"
  • 好奇心
  • 勘探
  • 四处玩耍
  • 我认为这个简单的缓存对于我的用例来说会更简单,因为我想以一种简单的方式将基于"REF"的"域模型"带到客户端:就好像客户端在服务器上一样,网络将是无限快和零延迟(这是缓存将模拟的)。

考虑构建丰富的动态 Web UI 需要解决哪些问题,以及哪些库/层通常会为您处理这些问题。

1. DOM 事件(点击等)需要触发状态更改

这相对容易。DOM 节点公开基于回调的侦听器 API,该 API 可以直接适应任何架构。

2. 状态更改需要触发对 DOM 节点的更新

这更棘手,因为它需要可维护的方式高效完成。您不希望在状态更改时从头开始重新渲染整个组件,并且您也不想编写大量 jquery 风格的意大利面条代码来手动更新 DOM,因为即使在运行时效率高,这也太容易出错。

这个问题主要是为什么像 React 这样的库存在,他们将其抽象到虚拟 DOM 后面。但是你也可以在没有虚拟DOM的情况下将其抽象出来,就像我自己的层流库一样。

放弃解决此问题的库解决方案仅适用于更简单的应用程序。

3. 组件应该能够读/写全局状态

这是通量/冗余解决的部分。具体来说,这些是问题 #1 和 #2 再次出现,除了应用于全局状态而不是组件状态。

4. 缓存

缓存很难,因为缓存需要在某个时候失效,除了上面的其他所有内容之上。

助焊剂/冗余对此根本没有帮助。其中一个有帮助的库是 Relay,它的工作方式与您提出的解决方案非常相似,只是更加详细,并且位于 React 和 GraphQL 之上。阅读其文档将帮助您解决问题。如果你不需要整个 React/GraphQL 包袱,但你需要了解现有技术,你绝对可以在普通 Scala 中实现一小部分 Relay 的功能.js。

5. 序列化和类型安全

这是此列表中唯一与Scala相关的问题.js而不是一般的Javascript和SPA。

Scala 对象需要序列化才能通过网络传输。进入JSON,protobufs或其他任何东西,但你需要一个不涉及容易出错的手动工作的系统。有许多 Scala.js 库可以解决这个问题,例如 upickle、Autowire、endpoints、sloth 等。关键词:"Scala JSON 库"或">Scala 类型安全 RPC",具体取决于您想要哪种解决方案。


我希望这些原则足以作为答案。当您了解这些问题时,您的解决方案是否适用于给定的用例应该很明显。实际上,您没有描述解决方案如何解决问题 2、4 和 5。您可以使用我提到的一些库,也可以使用类似的想法/算法实现自己的解决方案。


在次要的技术说明中,请考虑为您的缓存层实现一个异步的、基于未来的 API,以便它返回Future[Entity]而不是Loading | Entity

最新更新