Use Portals https://reactjs.org/docs/portals.html来自react-dom
图书馆:
门户提供了一种一流的方法来将子组件渲染到存在于父组件 DOM 层次结构之外的 DOM 节点中。
const HeaderPortal = ReactDOM.createPortal(<Header />, document.getElementById('header'))
const SideBarPortal = ReactDOM.createPortal(<SideBar />, document.getElementById('sidebar'))
const store = createStore(/* ... */)
ReactDOM.render(
<YourDataStoreProvider store={store}>
<HeaderPortal />
<SideBarPortal />
</YourDataStoreProvider>,
document.getElementById('root') // assuming you have an empty "dummy" node with that id
);
只需将您的应用程序渲染到 DOM 中任何位置的容器中或创建一个新的“虚拟”节点即可。在我的示例中,我假设有一个空节点,其 idroot
。然后将其他组件渲染到门户中。
redux store 可以在不同的 ReactDOM 之间工作吗?
您的应用程序将像完全渲染到同一个容器中一样工作。如果您使用门户,您的组件将位于具有相同上下文的同一组件树中,同时在其他地方呈现。
我应该使用门户吗?
使用门户通常旨在用于视觉上需要“突破”其容器的组件,例如模式或对话框。但您也可以使用它们来创建可以在任何地方呈现的类似小部件的组件。
创建通用 Portal 组件
您还可以创建一个通用的<Portal>
给定容器创建门户的组件id
:
import {createPortal} from 'react-dom';
const Portal = ({children, container}) => createPortal(
children,
document.getElementById(container),
);
export default Portal;
并这样使用它:
ReactDOM.render(
<YourDataStoreProvider store={store}>
<Portal container="header">
<Header />
</Portal>
<Portal container="sidebar">
<SideBar />
</Portal>
</YourDataStoreProvider>,
document.getElementById('root')
);
EDIT:
您需要 DOM 中的一个节点来渲染您的应用程序。这可以是您创建的新 DOM 元素,也可以是您已有的容器之一。鉴于您使用<Portal>
上面的组件也可能看起来像这样:
ReactDOM.render(
<YourDataStoreProvider store={store}>
<Header /> // this will be visible in your header container
<Portal container="sidebar">
<SideBar /> // this will be rendered to the sidebar container
</Portal>
</YourDataStoreProvider>,
document.getElementById('header')
);
这将使您的应用程序呈现在header
容器。但只有你的<Header>
组件实际上在该容器中具有 DOM 表示形式。侧边栏将呈现在sidebar
门户网站上的容器。但他们仍然会共享相同的反应组件树并拥有相同的商店提供者。