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:

JavaScript
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:

HTML / XML
<div>
  <button>Save</button>
  <button>Cancel</button>
</div>

If the wrapper is unnecessary, you can replace it with a Fragment.

JavaScript
function UserActions() {
  return (
    <>
      <button type="button">Save</button>
      <button type="button">Cancel</button>
    </>
  );
}

React renders the buttons without adding a wrapper element.

HTML / XML
<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:

JavaScript
<>
  <h2>Account Settings</h2>
  <p>Manage your account details.</p>
</>

The long syntax uses the Fragment component:

JavaScript
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.

JavaScript
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.

JavaScript
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.

JavaScript
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.

JavaScript
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.

JavaScript
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

addEventListener()

Registers an event listener for the Fragment's child elements.

removeEventListener()

Removes a previously registered event listener.

dispatchEvent()

Dispatches an event through the Fragment instance's supported behavior.

focus()

Moves focus to an appropriate focusable child.

focusLast()

Moves focus to an appropriate focusable child near the end of the group.

blur()

Removes focus from the relevant focused child.

getClientRects()

Retrieves the client rectangles of the Fragment's child elements.

observeUsing()

Uses a supported observer, such as a ResizeObserver, to observe the child elements.

unobserveUsing()

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.

JavaScript
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:

JavaScript
<>
  <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:

JavaScript
<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

  1. No extra wrapper DOM element is required.

  2. Related child elements can be managed as a group.

  3. Group-level operations can reduce the need for multiple individual refs.

  4. The existing DOM structure remains unchanged, which can help with layout-sensitive components.

Disadvantages

  1. Fragment refs are experimental and are not available in every React release.

  2. The Fragment instance is not a normal DOM element.

  3. Developers must understand the behavior of each supported group-level operation.

  4. 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.