请在 Clojure 2024 状态调查 中分享您的想法!

欢迎!请参阅 关于 页面以了解更多关于该功能的信息。

投票数量:+1

在热重载中,是否有一种方法只重新渲染受影响的应用程序部分呢?

Figwheel 文档中只提到重新挂载整个应用程序(在这种情况下,组件的所有本地状态都会丢失):https://figwheel.org/docs/hot_reloading.html#re-rendering-ui-after-saving-a-file

在 shadow-cljs 文档中还没有找到与此相关的内容。我见过的所有应用程序要不完全不支持热重载重渲染,要不就是全量重挂载。

那么,比较热重载前后 VDOM 的障碍是什么?或这是否已经实现?

尽管 Figwheel/shadow-cljs 与 React/VDOM 独立,但预期它们不会实现这样的行为,但可能有一些库或明确的解决方案呢?

共有2个答案

投票数量:+2

事实上,它并不是“重新挂载”,而仅仅是一个更新,并不意味着应用程序的整个 DOM 都被替换。调用顶级 render 与更新组件没有区别,React 仍然像平常一样执行 diff 和 patch。

by
编辑 by
嗯,可能我应该上传一些示例库,但 `reagent/render-component` 确实为我重新渲染了整个应用。也许你手头有一个参考项目,我可以比较并找出我错在哪里?
by
上传了最小化示例:https://github.com/fjolne/reagent-hot-reload

如果输入字段输入了一些文本,然后更改了标题的文本,热重新加载时的重新渲染将清除输入。
by
编辑 by
在这种情况下这是预期的,因为输入值没有存储在任何地方,除了DOM,所以从React的角度来看,输入中没有值。

纠正:这仍在Reagent中发生,但对于纯React不是这种情况。我猜这可能与Reagent自己关于本地状态的理解有关。
by
但是,如果输入字段不在diff中,为什么还要更新它?使用Reagent atomic来保存数据而不是DOM时也存在同样的行为。

更新:已经看到更正,感谢您深入探讨:)
投票数量:+2

一般来说,像fulcrore-frame这样的框架对于状态和状态管理都有明确的规定。使用它们。

在工具级别上做这件事会非常困难,这就是figwheel和shadow-cljs都只处理重新加载代码的原因,而将状态管理留给实际的应用程序。甚至不确定在没有完全限制你可以做什么的情况下,是否可以在工具级别上做到这一点。

我高度依赖于re-frame,但在某些情况下(简单的表单、下拉展开状态等),使用本地状态似乎比生成re-frame事件处理器/订阅更简洁。
此外,如上所述,React本身确实处理了这一点。那么为什么在重新加载状态之前和之后之间直接输出常规的VDOM diff就不可能呢?
如果你将对纯JS应用相同的快速重载方法,React本身对此不会有任何不同。

导致“替换”的真正原因是,在通过热重载重新定义函数时,`(identical? old new)`返回false。所以,在你的示例中,`app`和`form`有“新”的定义,因此React将它们替换。如果你只是从REPL调用`(mount!)`,`input`状态就不会被更改,它会“幸存”,因为实际的diff没有替换实际的DOM节点。
by
哦,不知道比较也是在函数本身进行的,这解释了很多,谢谢!
...