React Portal 提供了一种将子节点渲染到存在于父组件 DOM 层级之外的 DOM 节点的方法。这通常用于当你需要子组件脱离父组件的层级,例如在弹窗(modals)或者提示框(tooltips)的场景中。
在 React Portal 中使用 React Hook 和在普通组件中使用没有什么不同。下面我将通过创建一个简单的模态框(modal)组件来演示如何在 React Portal 中使用 React Hook。
首先,假设我们有一个 modal 的 root 元素在 HTML 文件中:
html<!-- public/index.html --> <body> <div id="app"></div> <!-- React 应用的根节点 --> <div id="modal-root"></div> <!-- Portal 的根节点 --> </body>
接下来,我们创建一个 Modal
组件,它将使用 useState
和 useEffect
这两个 Hook,以及 ReactDOM.createPortal
来渲染内容到 modal-root
:
jsximport React, { useState, useEffect } from 'react'; import ReactDOM from 'react-dom'; // Modal 组件 const Modal = ({ children }) => { // 创建一个 div 元素,用来渲染 modal 的内容 const [container] = useState(() => document.createElement('div')); useEffect(() => { const modalRoot = document.getElementById('modal-root'); modalRoot.appendChild(container); // 组件卸载时的清理函数 return () => { modalRoot.removeChild(container); }; }, [container]); // 依赖数组中的项确保只在组件挂载和卸载时执行 // 使用 React Portal 将 children 渲染到新的 DOM 节点 return ReactDOM.createPortal( children, container ); }; // 使用 Modal 组件 const App = () => { const [modalVisible, setModalVisible] = useState(false); return ( <div> <button onClick={() => setModalVisible(true)}>显示模态框</button> {modalVisible && ( <Modal> <div style={{ backgroundColor: 'white', padding: '20px' }}> <p>这是模态框的内容</p> <button onClick={() => setModalVisible(false)}>关闭模态框</button> </div> </Modal> )} </div> ); }; export default App;
在上面的 Modal
组件中:
- 使用
useState
创建了一个container
,它是一个 DOM 元素,在组件的生命周期内保持不变。 useEffect
用来处理挂载和卸载逻辑,确保container
被添加到modal-root
,并且在组件卸载时移除。ReactDOM.createPortal
方法用来在container
里渲染Modal
组件的子元素。
App
组件中包含了一个按钮,用于切换模态框的可见性,以及一个条件渲染的 Modal
组件,它显示了如何实现一个基本的模态框功能。在这个例子中,useState
用于控制模态框的显示状态。
这就是在 React Portal 中使用 React Hook 的方式,你可以像在普通组件中一样,在 Portal 中使用诸如 useState
, useEffect
, useContext
, useReducer
等 Hook。
2024年6月29日 12:07 回复