我有一个定义的
<custom-web-component />
,它可能会在基于 React 的应用程序运行时出现在 DOM 中的任何位置。 <custom-web-component />
的 connectedCallback()
告诉其他地方的 <Manager />
反应组件到 createPortal(<Foo />, this)
,在 <custom-web-component />
的位置注入更多反应内容。
注入的内容似乎可以访问 React Context,无论它安装在 React 树中的什么位置,
<Manager />
都可以使用该上下文。这对我来说对于大多数 React 上下文都很好,因为我可以确保 <Manager />
也位于必要的上下文提供程序中。
我的麻烦是react-router-dom的目的对react树中的放置更加敏感。由于
<Manager />
靠近反应树的根部,与 <Foo />
只是作为典型子元素安装在那里相比, "/route/segments/*"
不知道嵌套路由已经匹配了哪些 <Foo />
。 <Foo />
的路由路径基本上需要是相对于根的,这是不可取的。
我想通过以某种方式从
<custom-web-component />
的父级窃取上下文并使用 <UNSAFE_RouteContext.Provider value={parentContext } />
将 <Foo />
包裹在门户内恢复路由器上下文来恢复更直观的路由支持。
但是如何获得
parentContext
呢?同样,<custom-web-component />
可能会放置在任何地方(通过非反应代码),甚至放置在其他此类门户内。我无法在 Web 组件内执行 parentContext = React.useContext(UNSAFE_RouteContext)
,因为它不是反应功能组件。
我最好的想法是1)以某种方式在反应树中找到
<custom-web-component />
的实例,然后2)以某种方式从中提取路由器上下文(或其父级?)。有没有办法完成这两个步骤?
你的问题很复杂,特别是关于react-router-dom的上下文敏感性。由于
<custom-web-component />
不是 React 功能组件,因此像 useContext
这样的典型 React 方法将不起作用。
解决此问题的一种方法可能是将路由器上下文作为 props 传递给
<Manager />
,然后在创建门户时将其传递给 <Foo />
。您可以在 <custom-web-component />
实例化点捕获路由器上下文(假设此时它位于 React 功能组件内),然后将其转发到 <Manager />
。
另一种不太传统的方法是从
<custom-web-component />
向上遍历 DOM,找到具有路由器上下文的最近父级,然后将其传回 <Manager />
。这更加hacky并且可能不太可靠。
考虑到限制,我认为没有完美的解决方案,但这些方法可能为您提供一种手动传递所需上下文的方法。