In React development, createPortal
is a powerful API that allows developers to render child nodes to a DOM node that is outside the parent component's DOM hierarchy. This technology is particularly suitable for scenarios where you need to control the placement of child components in the DOM, such as modals, tooltips, and floating menus.
Basic Usage of createPortal
createPortal
requires two parameters: the React child element to be rendered and a DOM element, which is the target container for the child element. The syntax is as follows:
createPortal(child, container)
- child: A React node, i.e., the content you want to render.
- container: A DOM element that represents the mounting target for the Portal.
Usage Scenarios
- Modal: Modals often need to break out of the normal document flow and be centrally displayed globally, often accompanied by a background overlay. Using
createPortal
allows you to render modal content under the body tag, facilitating global control. - Tooltips: Tooltips usually dynamically display based on mouse position. Using
createPortal
can easily implement this behavior without being affected by the position of the parent component. - Context Menus: Custom context menus need to be displayed in specific locations. Using
createPortal
can prevent display issues caused by theoverflow
property of the parent container.
Example: Creating a Simple Modal
import React, { useState } from 'react'; import ReactDOM from 'react-dom'; function Modal({ children, onClose }) { return ReactDOM.createPortal( <div className="modal"> <div className="modal-content"> {children} <button onClick={onClose}>Close</button> </div> </div>, document.body ); } function App() { const [modalVisible, setModalVisible] = useState(false); const openModal = () => setModalVisible(true); const closeModal = () => setModalVisible(false); return ( <div> <button onClick={openModal}>Open Modal</button> {modalVisible && <Modal onClose={closeModal}>This is a modal</Modal>} </div> ); } export default App;
In this example, we defined a Modal
component that takes children
and onClose
as parameters. This component uses createPortal
to render modal content to the modal-root
node. Thus, no matter where the Modal
component is called from, the rendered content will appear under modal-root
, ensuring the modal can overlay other interface elements.
If not mounting to the body
node, we can use the ref
creation method:
// App.js or other parent Code import React, { useRef } from 'react'; import ReactDOM from 'react-dom'; import Modal from './Modal'; // Assuming your Modal component is separate function App() { const modalRootRef = useRef(null); return ( <div> <div ref={modalRootRef}></div> {/* Mounting point for the modal */} <Modal modalRootRef={modalRootRef}>Hello, modal!</Modal> </div> ); } export default App; // Modal.js import React from 'react'; import ReactDOM from 'react-dom'; function Modal({ children, modalRootRef }) { return modalRootRef.current ? ReactDOM.createPortal( <div className="modal"> <div className="modal-content"> {children} </div> </div>, modalRootRef.current ) : null; } export default Modal;
Performance and Considerations
While createPortal
offers great flexibility, it must be used cautiously. Improper use can lead to performance issues, especially when you frequently create and destroy Portals. Additionally, when using Portals, you should also note:
- Ensure the Portal's mounting node is available throughout the application's lifecycle.
- Using Portals may lead to some unexpected style inheritance issues because their position in the DOM tree has changed.
Comments
0 Comments