React developers often need to work with several DOM elements at the same time. For example, you might want to focus a group of buttons, attach an event listener to several elements, or measure the positions of multiple elements on a page.
One common solution is to place the elements inside a wrapper <div>. However, adding a wrapper is not always desirable. It can affect CSS layouts, introduce unnecessary DOM elements, or cause problems when working with grid and flexbox layouts.
React Fragments help solve the extra-wrapper problem by allowing multiple elements to be grouped without creating an additional DOM node. Fragment refs extend this idea by providing a way to interact with the DOM elements inside a Fragment as a group.
There is one important detail: Fragment refs are an experimental React feature available in Canary builds, not a generally available feature that every stable React application can use. Before using them, check whether your React version supports the API.
What Is a React Fragment?
A React Fragment allows a component to return multiple elements without adding an extra element to the DOM.
Consider this example:
function UserActions() {
return (
<div>
<button type="button">Save</button>
<button type="button">Cancel</button>
</div>
);
}This component creates a <div> around the two buttons.
The resulting HTML looks like this:
<div>
<button>Save</button>
<button>Cancel</button>
</div>If the wrapper is unnecessary, you can replace it with a Fragment.
function UserActions() {
return (
<>
<button type="button">Save</button>
<button type="button">Cancel</button>
</>
);
}React renders the buttons without adding a wrapper element.
<button>Save</button>
<button>Cancel</button>This is useful when the parent layout expects specific elements as direct children, such as when using CSS Grid or Flexbox.
Short and Long Fragment Syntax
React provides two ways to write a Fragment.
The short syntax uses empty angle brackets:
<>
<h2>Account Settings</h2>
<p>Manage your account details.</p>
</>The long syntax uses the Fragment component:
import { Fragment } from "react";
function AccountSettings() {
return (
<Fragment>
<h2>Account Settings</h2>
<p>Manage your account details.</p>
</Fragment>
);
}Both approaches group elements without creating a wrapper DOM element.
The long syntax is required when you need to provide a key to a Fragment in a list. It is also the syntax used when working with the experimental Fragment ref API.
What Are React Fragment Refs?
A normal React ref provides access to a particular DOM element or another value. For example, you can attach a ref to an input and use it to focus that input.
import { useRef } from "react";
function SearchBox() {
const inputRef = useRef(null);
function focusInput() {
inputRef.current?.focus();
}
return (
<div>
<input ref={inputRef} type="text" />
<button type="button" onClick={focusInput}>
Focus Search
</button>
</div>
);
}This works because the ref points directly to the input element.
A Fragment does not create a DOM element, so it cannot provide a normal element reference. Fragment refs introduce a different approach: in supported experimental React builds, a ref can be attached to a Fragment to access a Fragment instance that provides operations over its child DOM elements.
Instead of managing a separate ref for every button, you can work with the group through the Fragment instance.
The important difference is that the ref does not point to a wrapper element. There is no wrapper element in the DOM.
How to Use a Fragment Ref
The following example demonstrates the experimental API. It assumes you are using a React Canary build and matching React type definitions that support Fragment refs.
Step 1: Import React Hooks and Fragment
Start by importing Fragment, useRef, and useEffect.
import { Fragment, useRef, useEffect } from "react";The useRef Hook stores the reference, while useEffect is used to interact with the DOM after React has committed the elements.
Step 2: Create a Fragment Ref
Create a ref and attach it to the Fragment.
const actionsRef = useRef(null);The ref initially contains null. After React mounts the component, a supported Fragment ref can provide the Fragment instance.
Step 3: Access the Child Elements
Here is a complete example that attaches an event listener to the elements inside the Fragment.
import { Fragment, useRef, useEffect } from "react";
function UserActions() {
const actionsRef = useRef(null);
useEffect(() => {
const fragment = actionsRef.current;
if (!fragment) {
return;
}
function handleClick(event) {
console.log("Clicked element:", event.target);
}
fragment.addEventListener("click", handleClick);
return () => {
fragment.removeEventListener("click", handleClick);
};
}, []);
return (
<Fragment ref={actionsRef}>
<button type="button">Save</button>
<button type="button">Cancel</button>
<button type="button">Delete</button>
</Fragment>
);
}
export default UserActions;In this example, the Fragment instance manages the event listener for its child elements without requiring a wrapper <div>.
The effect also removes the listener during cleanup. This is important because an event listener that is not removed can cause unwanted behavior when a component is unmounted or its effects are restarted.
Remember that this example depends on the experimental Fragment ref API. It will not work in React versions that do not support refs on Fragments.
Working With Focus Across Multiple Elements
One useful application of Fragment refs is managing keyboard focus across a group of elements.
Imagine a dialog containing several buttons. You may want to move focus to the first or last focusable element when a particular action occurs.
With individual refs, you might need to create and maintain a separate ref for every button. A supported Fragment instance can provide group-level focus operations instead.
import { Fragment, useRef } from "react";
function DialogActions() {
const actionsRef = useRef(null);
function focusFirstAction() {
actionsRef.current?.focus();
}
function focusLastAction() {
actionsRef.current?.focusLast();
}
return (
<section>
<h2>Confirm Action</h2>
<Fragment ref={actionsRef}>
<button type="button">Confirm</button>
<button type="button">Cancel</button>
<button type="button">Help</button>
</Fragment>
<div>
<button type="button" onClick={focusFirstAction}>
Focus First Action
</button>
<button type="button" onClick={focusLastAction}>
Focus Last Action
</button>
</div>
</section>
);
}
export default DialogActions;The focus() and focusLast() operations are part of the experimental Fragment instance API. Their behavior depends on the supported elements and the implementation provided by the React version you use.
For production dialogs, you must also consider focus trapping, Escape-key handling, and returning focus to the element that opened the dialog. Focusing the first or last element alone does not implement a complete accessible dialog.
Other Operations Available Through Fragment Instances
Depending on the experimental React version, a Fragment instance can expose operations for interacting with its child DOM elements.
Operation | Purpose |
|---|---|
| Registers an event listener for the Fragment's child elements. |
| Removes a previously registered event listener. |
| Dispatches an event through the Fragment instance's supported behavior. |
| Moves focus to an appropriate focusable child. |
| Moves focus to an appropriate focusable child near the end of the group. |
| Removes focus from the relevant focused child. |
| Retrieves the client rectangles of the Fragment's child elements. |
| Uses a supported observer, such as a |
| Stops observing the child elements with the specified observer. |
The exact methods and their behavior should be checked against the React Canary version and its type definitions. Do not assume that every method is available in every stable React release.
Measuring Multiple Elements
Suppose you have several navigation links and need to inspect their positions for a custom layout calculation.
A normal ref attached to a wrapper <div> gives you the wrapper's bounding rectangle. A Fragment does not create that wrapper, so there is no single wrapper rectangle to retrieve.
The experimental getClientRects() operation can instead return rectangles associated with the child elements.
import { Fragment, useRef } from "react";
function Navigation() {
const navigationRef = useRef(null);
function inspectPositions() {
const fragment = navigationRef.current;
if (!fragment) {
return;
}
const rectangles = fragment.getClientRects();
console.log("Navigation element positions:", rectangles);
}
return (
<nav>
<Fragment ref={navigationRef}>
<a href="/home">Home</a>
<a href="/products">Products</a>
<a href="/contact">Contact</a>
</Fragment>
<button type="button" onClick={inspectPositions}>
Inspect Positions
</button>
</nav>
);
}
export default Navigation;This example is intended for a React build that supports Fragment refs. It illustrates the idea of measuring several child elements without introducing a wrapper.
In a real application, remember that element positions can change after resizing, scrolling, font loading, or content updates. Avoid measuring layout repeatedly when a single measurement or an appropriate observer would be sufficient.
Fragment Refs vs. Wrapper Elements vs. Individual Refs
Fragment refs are not a replacement for every other ref technique. The right choice depends on whether you need a real DOM element or only need to work with a group of elements.
Approach | Adds a DOM element? | Best use case | Main limitation |
|---|---|---|---|
Fragment without a ref | No | Grouping elements without changing the DOM structure | Does not provide direct DOM access |
Wrapper element with a ref | Yes | Measuring, styling, or interacting with a real container | Can affect layout and DOM structure |
Individual element refs | No extra wrapper | Controlling specific inputs, buttons, or other elements | Requires managing multiple refs |
Experimental Fragment ref | No | Performing supported operations across a group of child elements | Availability and API behavior depend on the React build |
For most applications using stable React releases, a wrapper element or individual refs remain practical choices.
Use an experimental Fragment ref only when its group-level operations provide a clear benefit and your project can safely depend on that React version.
Best Practices for Using Fragment Refs
1. Check React Version Support
Do not assume that Fragment refs work just because your project uses a recent React version.
Confirm that your React build and type definitions support the feature. If you are using TypeScript, check whether the Fragment ref types are available in the installed React declarations.
2. Use Refs for DOM Operations
Refs are useful for imperative operations such as focus management, event listeners, and measuring elements.
Do not use them as a replacement for React state when the interface needs to update in response to user actions.
3. Clean Up Event Listeners
Remove event listeners and disconnect observers when they are no longer needed.
This keeps the component lifecycle predictable and reduces the risk of duplicate handlers or unnecessary work.
4. Keep Accessibility in Mind
A Fragment does not create a semantic container. It does not behave like a <nav>, <section>, or <div>.
If the elements need a meaningful semantic parent, use an appropriate HTML element. Avoid removing a wrapper when that wrapper is necessary for accessibility or correct document structure.
5. Avoid Depending on Experimental APIs Without a Plan
Experimental APIs may change before becoming generally available. If your application uses Fragment refs, document the React version requirement and test the behavior during upgrades.
For a production application that cannot use a Canary build, use a supported alternative until the feature is available in the React release you have chosen.
Common Mistakes and Troubleshooting
Using the Short Fragment Syntax With a Ref
This does not work:
<>
<button ref={actionsRef}>Save</button>
</>The ref here belongs to the button, not to the Fragment. The short syntax does not accept a Fragment ref.
In a supported experimental build, use the long syntax:
<Fragment ref={actionsRef}>
<button type="button">Save</button>
</Fragment>Assuming a Fragment Ref Points to a DOM Node
A Fragment does not produce a DOM element. Its ref provides a Fragment instance with supported group-level operations, not a normal HTML element.
You should not expect to use properties such as fragmentRef.current.style or fragmentRef.current.getBoundingClientRect() as you would with a DOM element.
Using Fragment Refs in an Unsupported React Version
If React reports that the ref is invalid or your type checker rejects it, check the installed React version and type definitions first.
Do not try to solve a version limitation by suppressing TypeScript errors. Use a supported wrapper or individual refs instead.
Forgetting Effect Cleanup
Adding listeners without removing them can result in duplicate behavior when effects run more than once or the component is remounted.
Always pair listener registration with cleanup, and apply the same principle to observers and other external resources.
Advantages and Disadvantages
Advantages
No extra wrapper DOM element is required.
Related child elements can be managed as a group.
Group-level operations can reduce the need for multiple individual refs.
The existing DOM structure remains unchanged, which can help with layout-sensitive components.
Disadvantages
Fragment refs are experimental and are not available in every React release.
The Fragment instance is not a normal DOM element.
Developers must understand the behavior of each supported group-level operation.
Production applications may need alternative implementations until the feature is supported by their chosen React version.
Summary
React Fragments allow components to return multiple elements without adding an unnecessary wrapper to the DOM. Fragment refs build on this idea by providing experimental group-level access to child elements, enabling operations such as event handling, focus management, and measuring element positions.
However, Fragment refs should not be treated as a standard feature available in every React application. Their availability depends on the React build, and the API may change.
For stable production applications, use a wrapper element or individual refs when appropriate. Consider Fragment refs when you specifically need to work with multiple DOM elements as a group and can use a React version that supports the experimental API.


Join the conversation! Your thoughts help the community grow.