React.Fragment is a special component that can only receive key and children as props. Passing any other props like className, style, or custom attributes will trigger this validation warning.
React.Fragment is a lightweight wrapper that allows you to group multiple elements without adding extra nodes to the DOM. However, Fragment is not a regular React component—it's a special construct with strict limitations on what props it can receive. Unlike normal React components that can accept any props, Fragment can only accept two specific props: `key` (used when rendering lists) and `children` (the elements to group). This restriction exists because Fragment doesn't render an actual DOM element, so props like className, style, id, or event handlers have nowhere to apply. When you try to spread props onto a Fragment or explicitly pass invalid props, React will issue a warning: "Invalid prop [propName] supplied to React.Fragment. React.Fragment can only have key and children props." This validation helps prevent mistakes where you might accidentally try to style or attach behavior to something that doesn't exist in the DOM.
If you need to apply props like className or event handlers, use an actual DOM element (div, span, section) instead of Fragment:
// ❌ This will cause the warning
function BadExample(props: any) {
return (
<React.Fragment {...props}>
<h1>Title</h1>
<p>Content</p>
</React.Fragment>
);
}
// ✅ Use a div to accept props
function GoodExample(props: any) {
return (
<div {...props}>
<h1>Title</h1>
<p>Content</p>
</div>
);
}If the extra wrapper is a concern for styling, you can use a semantic element like <section> or a <div> with minimal styling impact.
If you must use Fragment but receive props from parent components, explicitly filter out invalid props:
// ✅ Only pass key prop to Fragment
function FilteredFragment({ children, key, ...otherProps }: any) {
// otherProps are intentionally not spread to Fragment
return <React.Fragment key={key}>{children}</React.Fragment>;
}
// Or destructure and discard invalid props
function SafeComponent({ className, style, ...validProps }: any) {
return (
<>
{validProps.children}
</>
);
}This approach is useful when wrapping third-party components that pass extra props.
Fragment is designed for simple grouping. If you don't need to pass any props, use the shorthand syntax:
// ✅ Fragment with no props (shorthand)
function SimpleComponent() {
return (
<>
<Header />
<Main />
<Footer />
</>
);
}
// ✅ Fragment with only key prop (full syntax required)
function ListComponent({ items }: { items: any[] }) {
return (
<>
{items.map((item) => (
<React.Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.definition}</dd>
</React.Fragment>
))}
</>
);
}Remember: only use React.Fragment when you explicitly need the key prop. Otherwise, use <></>.
If the warning comes from a third-party library, check for updates:
# Update to latest version
npm update library-name
# Or check for React 19 compatibility
npm outdatedCommon libraries that had this issue:
- TanStack Table (fixed in v8.11+)
- Headless UI (fixed in recent versions)
- Tiptap (check latest releases)
- React Native Reanimated (ensure Babel plugin matches version)
If no update is available, file an issue with the library maintainers or apply a local patch using patch-package.
Why Fragment has these restrictions:
Fragment doesn't create a real DOM node—it's purely a React construct for grouping. When React compiles your code, Fragments are essentially removed from the final output, leaving only their children. This is why props like className or onClick have nowhere to go.
Key prop is special:
The key prop is the only exception to Fragment's prop restrictions because it's not a DOM attribute—it's a React-specific prop used for reconciliation during list rendering. React needs keys to track which items changed, so Fragment supports it even though it doesn't render to the DOM.
React 18/19 stricter validation:
React 18 and 19 introduced stricter validation for Fragment props in development mode. Code that worked silently in React 17 may now show warnings, especially if you're using libraries that haven't updated their Fragment usage.
Performance considerations:
Using Fragment instead of unnecessary wrapper divs improves performance by reducing DOM node count. However, if you need styling or behavior, don't fight Fragment's limitations—just use a real element. The performance difference is negligible for most applications.
TypeScript strict typing:
If using TypeScript, Fragment's type signature only allows key and children:
type FragmentProps = {
key?: React.Key;
children?: React.ReactNode;
};Attempting to pass other props will cause TypeScript errors before runtime warnings appear.
React.FC expects children prop to be defined
React.FC no longer includes implicit children prop
Warning: You provided a `selected` prop to a form field without an `onChange` handler
You provided a 'selected' prop without an onChange handler
Failed to load source map from suspense chunk
How to fix "Failed to load source map from suspense chunk" in React
Prop spreading could cause security issues
Prop spreading could cause security issues
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency