React Reverse Portal is a utility library that enables the reparenting of rendered React elements within the DOM without triggering a re-render. Unlike standard React portals which allow an element rendered in one part of the React tree to be physically moved elsewhere in the DOM, reverse portals facilitate pulling an already rendered element from a source location into a target within the React tree. This mechanism is particularly useful for preserving internal React component state and inherent DOM element state (e.g., a playing video) when elements need to be moved, hidden, or reused across different parts of an application. The library is currently at version 2.3.0, actively maintained with a focus on stability and broad React version compatibility (16+). Key differentiators include its small bundle size, zero runtime dependencies, full TypeScript support, and the ability to define props at either the creation or usage location. It's designed for scenarios involving expensive-to-render components that benefit from being instantiated once and then dynamically placed or unplaced.
npm install react-reverse-portalVerified import paths — ran on the pinned version, not inferred.
This quickstart demonstrates creating a stable portal node with `createHtmlPortalNode`, rendering an expensive component into it using `InPortal`, and then moving that same component between two different `OutPortal` locations in the DOM. The `MyExpensiveComponent` maintains its internal state and only renders once, showcasing the library's primary benefit of state preservation during DOM reparenting.
Always initialize the `portalNode` within `React.useMemo` or `React.useRef` to ensure its stability across renders: `const portalNode = React.useMemo(() => portals.createHtmlPortalNode(), []);`
Check your project's `package.json` for `react` and `react-dom` versions and ensure they satisfy the peer dependency requirements (`^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0`). Upgrade or downgrade React/ReactDOM if necessary, or use an override/resolution in your package manager.
Review the official documentation and examples to grasp the 'pull' mechanism. Props can be provided to `InPortal` (initial state) or `OutPortal` (dynamic props, which will trigger re-renders of the content within the `InPortal`).
Ensure `InPortal` receives a `node` prop: `<InPortal node={portalNode}>...</InPortal>` where `portalNode` is a stable object created via `React.useMemo(() => createHtmlPortalNode(), [])`.Use ES Module imports: `import { InPortal, OutPortal, createHtmlPortalNode } from 'react-reverse-portal';` or `import * as portals from 'react-reverse-portal';`.Ensure props passed to `InPortal` or `OutPortal` (if applicable) are stable. If `InPortal`'s content relies on context, verify that context providers are not frequently re-mounting or providing unstable values. The `portalNode` itself *must* be stable.