Registry / web-framework / react-useportal

react-useportal

JSON →
library1.0.19jsnpmunverified

react-useportal is a utility React hook for creating and managing React Portals, a feature introduced in React 16 that allows components to render children into a DOM node that exists outside the DOM hierarchy of the parent component. Currently at version 1.0.19, the package simplifies common use cases such as modals, tooltips, dropdowns, and notifications. Key differentiators include built-in isomorphic Server-Side Rendering (SSR) support, full TypeScript compatibility, and a minimal dependency footprint (primarily `use-ssr`). Despite its utility, the project has seen very limited maintenance and updates in recent years, making its release cadence effectively dormant. It aims to abstract away the direct usage of `ReactDOM.createPortal` for a more React-hook-centric API.

npm install react-useportal
INSTALL
IMPORT
SIG · REACT-USEPORTAL
R
react-useportal
web-frameworkjavascriptv1.0.19
Install
Import
Disk
Pass rate
0/ 6
Env Coverage0 / 6
glibc
1822
musl
1822
Install & Compatibility
Where this runs
tested against v? · npm install
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
node 18226 runs
build_error
glibc
node 18226 runs
build_error
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

usePortal
import usePortal from 'react-useportal'
import { usePortal } from 'react-useportal'
The primary hook `usePortal` is a default export, not a named export. It returns a `Portal` component along with other utilities.
Portal
const { Portal } = usePortal()
import { Portal } from 'react-useportal'
The `Portal` component is returned by the `usePortal` hook, not directly imported from the package.
UsePortalOptions
import type { UsePortalOptions } from 'react-useportal'
For TypeScript users, import types using `import type` to avoid bundling unnecessary code.

This quickstart demonstrates basic stateless portal usage to `document.body` and a custom target, alongside a stateful example showing how to programmatically open and close a modal-like portal. It includes SSR guards for `document` access.

import React from 'react'; import usePortal from 'react-useportal'; function App() { // Basic usage: Portals content to document.body by default const { Portal: BodyPortal } = usePortal(); // Custom target: Portal content to a specific element // Ensure 'portal-root' exists in your HTML (e.g., public/index.html) const { Portal: CustomPortal } = usePortal({ bindTo: typeof document !== 'undefined' ? document.getElementById('portal-root') : null, // Ensure `document` is available for SSR compatibility }); // Stateful example with open/close controls const { Portal: StatefulPortal, openPortal, closePortal, isOpen } = usePortal(); return ( <div> <h1>React usePortal Examples</h1> <p>This text is rendered in the main application DOM.</p> <h2>Stateless Portal to document.body</h2> <BodyPortal> <p style={{ border: '2px solid blue', padding: '10px' }}> This content is portaled to the end of document.body. </p> </BodyPortal> <h2>Custom Target Portal</h2> <div id="portal-root" style={{ border: '2px dashed green', padding: '10px' }}> <p>This is the custom target element (e.g., in public/index.html).</p> <CustomPortal> <p style={{ border: '2px solid purple', padding: '10px' }}> This content is portaled into '#portal-root'. </p> </CustomPortal> </div> <h2>Stateful Portal (Modal Example)</h2> <button onClick={openPortal}>Open Stateful Portal</button> {isOpen && ( <StatefulPortal> <div style={{ position: 'fixed', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', backgroundColor: 'white', padding: '20px', border: '1px solid black', zIndex: 1000, }}> <h3>Hello from Stateful Portal!</h3> <p>You can control its visibility with buttons.</p> <button onClick={closePortal}>Close Modal</button> </div> </StatefulPortal> )} </div> ); } export default App;
Debug
Known issues
gotchaThe `react-useportal` package has not seen active development or maintenance in over three years. While functional for many use cases, it may not receive updates for compatibility with future React versions or address new bugs/security concerns.
fix
Evaluate alternatives like `react-portal` (if more actively maintained) or a custom `ReactDOM.createPortal` implementation for long-term projects or those requiring bleeding-edge React features.
affects: >=1.0.19
gotchaWhen using the `bindTo` option with `document.getElementById` or similar DOM APIs, ensure proper checks for `document` availability, especially in Server-Side Rendering (SSR) environments. Direct access to `document` on the server will cause errors.
fix
Wrap `document` access with `typeof document !== 'undefined'` or similar checks to conditionally execute client-side code, as shown in the quickstart example. This prevents 'document is not defined' errors during SSR.
affects: >=1.0.0
gotchaWhen creating many `usePortal` instances, especially for elements like tooltips that might appear on hover, there can be performance overhead due to `ReactDOM.createPortal()` being called immediately for each instance. This can lead to noticeable lag if not managed.
fix
Consider lazy initialization of portals or creating a single shared portal instance that dynamically updates its content for scenarios with a large number of potential portal triggers. The `programmaticallyOpen` option might also be useful to delay portal creation until needed.
affects: >=1.0.0
gotchaPortals, including those created with `react-useportal`, do not automatically handle accessibility concerns such as focus trapping, keyboard navigation, or ARIA attributes for modal dialogs. Implementing these correctly is crucial for an inclusive user experience.
fix
Manually implement WAI-ARIA authoring practices for interactive portal-based components (e.g., modals, tooltips), including focus management (trapping focus, restoring focus), keyboard navigation (Esc key to close), and appropriate ARIA roles and attributes.
affects: >=1.0.0
Errors
Common errors & fixes
ReferenceError: document is not defined
Attempting to access the `document` object during server-side rendering (SSR) without conditional checks, typically when using `bindTo: document.getElementById('...')`.
fix
Guard `document` access with `typeof document !== 'undefined' ? document.getElementById('my-id') : null` to ensure code runs only in a browser environment.
Error: Target container is not a DOM element.
The DOM element specified in the `bindTo` option either does not exist, or the component attempting to create the portal mounts before the target element is available in the DOM.
fix
Ensure the target DOM element exists before the portal tries to mount. For dynamically rendered targets, use a `ref` or `useEffect` to ensure the element is ready. For static targets, verify the ID matches an element in your `index.html`.
Events on elements inside the Portal bubble to parent components in the React tree, not the DOM tree.
React's event system processes events through the React component tree, regardless of the physical DOM placement of portals. This can be counter-intuitive for elements visually outside their parent.
fix
Use `event.stopPropagation()` on event handlers within the portal's content or on its overlay to prevent events from bubbling up to undesired parent components in the React tree.
Upgrade
Version history
1.0.19latest on npm
Audit
Dependencies
reactrequiredPeer dependency required for any React application.
react-domrequiredPeer dependency required for rendering React components to the DOM, especially for portals.
use-ssrrequiredRuntime dependency for handling Server-Side Rendering (SSR) logic.
Agent activity
4 hits · last 30 days
node
4
Resources