React’s Adjacent JSX elements must be wrapped in an enclosing tag error means that when you’re returning multiple JSX elements from a component, React doesn’t know how to render them as a single unit without an explicit parent. It expects a single root element, just like a browser expects a single <html> tag.
Here’s how to fix it, from most to least common causes:
1. Missing Fragment Wrapper (Most Common)
You’ve got two or more top-level elements directly inside your return statement.
- Diagnosis: Look at the
returnstatement of your component. Do you see something like this?return ( <h1>Hello</h1> <p>World</p> ); - Fix: Wrap the adjacent elements in a React Fragment. This is the preferred method as it doesn’t add an extra DOM node.
Or using the explicitreturn ( <> <h1>Hello</h1> <p>World</p> </> );Fragmentsyntax:import React from 'react'; return ( <React.Fragment> <h1>Hello</h1> <p>World</p> </React.Fragment> ); - Why it works: Fragments tell React to group these elements without introducing a new DOM element, satisfying the "single root" requirement.
2. Implicit Fragment in map (Common)
When you map over an array and return JSX, if the mapped function returns multiple elements directly, you’ll hit this.
- Diagnosis:
function MyList({ items }) { return ( <div> {items.map(item => ( <h2>{item.title}</h2> <p>{item.description}</p> ))} </div> ); } - Fix: Wrap the elements returned by the
mapcallback in a Fragment.
Note thefunction MyList({ items }) { return ( <div> {items.map(item => ( <React.Fragment key={item.id}> <h2>{item.title}</h2> <p>{item.description}</p> </React.Fragment> ))} </div> ); }keyprop is essential for lists. - Why it works: The
mapcallback, like any function returning JSX, needs a single root. The Fragment provides this for each item generated by the map.
3. Incorrectly Structured Conditional Rendering
When using conditional rendering (e.g., && or ternary operators), if the condition results in multiple sibling elements being rendered, you’ll see this error.
- Diagnosis:
function MyComponent({ isLoggedIn }) { return ( <div> {isLoggedIn && ( <h1>Welcome back!</h1> <p>You have new messages.</p> )} </div> ); } - Fix: Wrap the conditionally rendered elements in a Fragment.
function MyComponent({ isLoggedIn }) { return ( <div> {isLoggedIn && ( <> <h1>Welcome back!</h1> <p>You have new messages.</p> </> )} </div> ); } - Why it works: The
&&operator, when the left side is true, evaluates to the right side. If the right side is multiple elements, React sees them as adjacent and errors. The Fragment makes the right side a single JSX element.
4. Multiple Top-Level Elements in a Higher-Order Component (HOC)
If you’re building an HOC that returns a component, and that returned component directly renders multiple elements without a wrapper.
- Diagnosis:
function withWrapper(WrappedComponent) { return function EnhancedComponent(props) { return ( <WrappedComponent {...props} /> <p>Some extra info</p> ); } } - Fix: Wrap the returned elements in a Fragment within the HOC.
function withWrapper(WrappedComponent) { return function EnhancedComponent(props) { return ( <> <WrappedComponent {...props} /> <p>Some extra info</p> </> ); } } - Why it works: The
EnhancedComponentis the one directly returning JSX. It needs a single root element, which the Fragment provides.
5. Incorrectly Returning Multiple Components in a Parent Component
This is similar to the first point but often happens when you’re thinking about components as distinct units.
- Diagnosis:
function App() { return ( <Header /> <MainContent /> <Footer /> ); } - Fix: Wrap the multiple component calls in a Fragment.
function App() { return ( <> <Header /> <MainContent /> <Footer /> </> ); } - Why it works: Even though
Header,MainContent, andFooterare components that themselves return single root elements, when you call them directly within another component’sreturnstatement, React sees them as adjacent JSX elements that need a single parent.
6. Incorrectly Returning Multiple Elements from a Portaled Component
If you’re using ReactDOM.createPortal and the content you’re portal-ing consists of multiple adjacent elements.
- Diagnosis:
function MyModal({ children }) { return ReactDOM.createPortal( <div>{children}</div>, document.getElementById('modal-root') ); } function App() { return ( <MyModal> <h1>Modal Title</h1> <p>Modal Content</p> </Modal> ); } - Fix: Wrap the content passed to
createPortalin a Fragment.function MyModal({ children }) { return ReactDOM.createPortal( <> <h1>Modal Title</h1> <p>Modal Content</p> </>, document.getElementById('modal-root') ); } - Why it works:
createPortalalso expects a single root element to be rendered into the target DOM node. The Fragment ensures this.
The next error you’ll likely encounter if you’ve fixed all these is related to key props on lists, or perhaps a prop-drilling issue if your component structure becomes more complex.