试图在 Umbraco 的原始 HTML 中水化 ReactJS.net SSR 组件



我有一个Umbraco CMS松散地与 ReactJS.net 一起工作。我有一个根<App>组件,它采用(Umbraco 节点 ID 和路径)对象的数组prop,用于使用<Content>comp 为站点中的每个页面生成<Route><App>UmbracoViewPage中呈现,在客户端浏览器中呈现良好 - 使用@Html.ReactInitJavaScript(),它会按预期冻结。

<Content>组件使用dangerouslySetInnerHTML加载页面 HTML。我有一些自定义的 Umbraco 网格编辑器,它们不是在 ASP .NET 视图中生成常规标记,而是调用@Html.React()来呈现可能需要一两个prop的自定义 React 组件。

在初始页面加载时,网格 HTML 是在服务器端生成的,这些嵌套组件在浏览器中工作正常,因为 ReactJS.net 传递每个网格组件的ReactDOM.hydrate()调用(由@Html.ReactInitJavaScript()触发)。

但是,一旦前端路由发生变化,<App>就会根据路径挂载相关的<Content>comp,这将调用具有 Umbraco 节点 ID 的 UmbracoSurfaceController。该节点的页面网格 HTML 将像以前一样使用dangerouslySetInnerHTML返回和加载。

问题是我现在有原始 HTML,其中包含多个需要补水的 React 组件。因为它是在浏览器中加载的,所以不再有单独冻结所有组件的@Html.ReactInitJavaScript()调用。

我怎样才能做到这一点?

注意:回答我自己的问题,以防它帮助任何正在使用 Umbraco 和 React 并致力于更紧密集成的人。

TL;DR- 在我的内容 API 响应中包含组件名称、React ID 和 props 的列表,允许我的前端代码处理它,就像 ReactJS.NET 的@Html.ReactInitJavaScript助手一样(我认为)。

我的解决方案是修改我的SurfaceController以包含标记中呈现的所有 React 组件的列表。因此,它与ReactJS.NET的@Html.ReactInitJavaScript助手非常相似,但是在我的SurfaceControllerAPI方法中。

我扩展了 ReactJS.NET 的@Html.React帮助程序,以便有关调用的组件的详细信息也添加到我命名ReactComponentHydrator的自定义帮助程序服务(要点,每个请求的单例)*。对于每个组件,我存储组件名称(例如Component.ExampleComponent),HTML 标记中包含的 React ID(例如react_d1gC4eKqaUatZWfAdtjkTA)和随之而来的道具。

由此,在前端代码中,我将在通过dangerouslySetInnerHTML加载 HTML 后创建和水化每个组件。

*ReactJS.NET 似乎确实跟踪了调用的每个组件,但这是内部的,没有通过我能找到的任何 API 公开。