我有一个关于React的问题,这是React应用程序的简化版。
在应用程序中,我要呈现一个固定的主菜单和一个可选的辅助菜单,其内容由路由中呈现的内部组件控制。
辅助菜单也在应用程序的移动版本中的其他位置呈现。
function App() {
return <Router>
<PrimaryMenu/>
<SecondaryMenu/>
<LayoutContent/>
{/* This block is rendered only on mobile devices */}
<Responsive {...Responsive.onlyMobile}>
<SecondaryMenu/>
</Responsive>
</Router>;
}
LayoutContent将根据路由规则呈现实际的页面内容(使用Page
组件),每个页面组件都可以像这样呈现其自己的辅助菜单(例如page1拥有自己的子菜单,page2拥有另一个子菜单,page3却没有。)
<Page title='Page 1 - With secondary menu'>
<SecondaryMenuItems>
{/* I want this content as children of secondary menu in both mobile and desktop menubars */}
<li>Page 1 item 1</li>
<li>Page 1 item 2</li>
</SecondaryMenuItems>
</Page>
我试图通过使用React Contexts实现它,但是如果我将子节点存储在上下文中,则会触发无限渲染。我将其更改为在<SecondaryMenuItems/>
组件中使用id属性,但是该方法非常脆弱,并且也有一些缺点。
这是我的working example,它正在工作,但是正如我所说的那样,它非常脆弱:
此外,如果您切换到带有菜单的页面,然后转到第3页(没有菜单),则上一页菜单仍保留在屏幕上。
如何通过反应来做到这一点?有建议的方法吗?
表达我的问题的一种更简单的方法是“如何在不相关的组件(例如同级组件)之间传递一组反应节点”
我已经在收到提示的情况下完成了我的工作示例,现在通过将useRef
与ReactDOM.createPortal
结合起来,我获得了最终结果,该结果已在示例中显示。
这是React Portals的用例。门户网站可让您将页面中的辅助菜单项呈现到其他位置的辅助菜单容器中
您要做的就是在页面的渲染中调用React.createPortal,将渲染的元素和目标节点传递到其中,而不管其在DOM树中的位置如何
我已经在https://codesandbox.io/s/secondary-menu-example-vbm3x的门户网站上编辑了您的示例。当然,这是一个基本示例,为了方便起见,您可能希望将门户网站逻辑抽象到一个单独的组件中,并且/或者从父级传递dom引用,而不是在mount上调用getElementById。