我有一个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
助手非常相似,但是在我的SurfaceController
API方法中。
我扩展了 ReactJS.NET 的@Html.React
帮助程序,以便有关调用的组件的详细信息也添加到我命名ReactComponentHydrator
的自定义帮助程序服务(要点,每个请求的单例)*。对于每个组件,我存储组件名称(例如Component.ExampleComponent
),HTML 标记中包含的 React ID(例如react_d1gC4eKqaUatZWfAdtjkTA
)和随之而来的道具。
由此,在前端代码中,我将在通过dangerouslySetInnerHTML
加载 HTML 后创建和水化每个组件。
*ReactJS.NET 似乎确实跟踪了调用的每个组件,但这是内部的,没有通过我能找到的任何 API 公开。