Adjacent JSX elements must be wrapped in an enclosing tag

I’m a beginner to react and I’ve been trying to understand the basis. I’m confused with the exact meaning of the error: Adjacent JSX elements must be wrapped in an enclosing tag. Here’s the code in which the error occurs.

function App() {
  const name = "John";
  const isNameShowing = false;
  return (
    <div className="App">
      <header className="App-header">
        <h1>
          {isNameShowing ? (
            test
          ) : (
              <h1>test</h1>
              <h2>There is no name</h2>
          )}
        </h1>
      </header>
    </div>
  );
}

export default App; 

I understand that the error part occurs here in this block

     <h1>
          {isNameShowing ? (
            test
          ) : (
              <h1>test</h1>
              <h2>There is no name</h2>
          )}
     </h1>

The error says I’ve to put self enclosing tags or a parent div element. But isn’t it already enclosed within the main div element ?

Also isn’t the below part of the code already enclosed within the parent <h1> element around it?

          (
              <h1>test</h1>
              <h2>There is no name</h2>
          )

Inspite of having <h1> as a parent element and even if that doesn’t suffice, and the main div element being the parent element, the error still pops up. What exactly does being wrapped around the parent element mean to prevent this error ?

The error you’re encountering, “Adjacent JSX elements must be wrapped in an enclosing tag,” occurs because JSX (JavaScript XML) syntax requires that you enclose multiple JSX elements within a single parent element. In your code snippet, you’re trying to render two separate JSX elements within a ternary condition, and JSX doesn’t allow adjacent elements without a common parent element

1 Like

You can also check the docs.

1 Like

don’t those two separate JSX elements have h1 as the common parent element? And also everything is enclosed within a div element which is the main parent element here. I’m a beginner, so apologise if this is a silly question. Could you explain more

Hi, thank you for the link. I went through the rules. But don’t those two separate JSX elements in my code have h1 as the common parent element? And also everything is enclosed within a div element which is the main parent element here. I’m a beginner, so apologise if this is a silly question. Could you explain more

Hello!

Return is the culprit here.

Returning things in programming means you execute, leave and move on.

Under the hood this isn’t HTML, but two separate JavaScript objects.
If you return object 1 (h1), function or object 2 (h2) won’t be executed, you abandoned it.

If you want both, you will have to wrap them in an array (parent element in JSX), then both are executed.

2 Likes

don’t those two separate JSX elements in my code have <h1> as the common parent element? it works only when <div> or fragment.js is the common parent element, may I know why <h1> does not work as parent element.

don’t those two separate JSX elements in my code have <h1> as the common parent element? it works only when <div> or fragment.js is the common parent element, may I know why <h1> does not work as parent element.

@liveforhope You really do not need to post the same question so many times. Also, I think this was explained already.


From the docs.

JSX looks like HTML, but under the hood it is transformed into plain JavaScript objects. You can’t return two objects from a function without wrapping them into an array. This explains why you also can’t return two JSX tags without wrapping them into another tag or a Fragment.

It is the actual return/the elements the expression evaluates to. This doesn’t work with a map either.

Doesn’t work:

function App() {
  const numbers = [1, 2, 3, 4, 5];

  return (
    <div>
      {numbers.map((number) => (
        <h1>{number}</h1>
        <h2>{number}</h2>
      ))}
    </div>
  );
}

Yes, the map is wrapped in a div, but the two elements returned are not.

We can use the Babel Repl to see the output. If we simplify this it is easier to see.

function App() {
  return (
    <div className="App">
      <h1>test</h1>
      <h2>test2</h2>
    </div>
  );
}
export default App;
import { jsx as _jsx } from "react/jsx-runtime";
import { jsxs as _jsxs } from "react/jsx-runtime";
function App() {
  return /*#__PURE__*/_jsxs("div", {
    className: "App",
    children: [/*#__PURE__*/_jsx("h1", {
      children: "test"
    }), /*#__PURE__*/_jsx("h2", {
      children: "test2"
    })]
  });
}
export default App;

You can see the two elements are children which is an array of two _jsx calls.

You could technically put them directly in an array as well instead of wrapping them in an element.

function App() {
  const name = 'John';
  const isNameShowing = false;
  return (
    <div className="App">
      <header className="App-header">
        <h1>
          {isNameShowing ? test : [<h1>test</h1>, <h2>There is no name</h2>]}
        </h1>
      </header>
    </div>
  );
}

export default App;
2 Likes

Hi, thank you for the answer. I finally understood most of it. Just one final question, could you explain more on why In your first example, inspite of the map being wrapped in a div, the two JSX expression returned at the bottom level are considered. Doesn’t the function function App()return the div first ? Inside the div, there is this map function and then the JSX expressions. But the return actually returns the div, right ? Or does the return statement inspite of having one parent div, does not return div, but returns only the actual JSX expressions at the bottom level ?

You can only have expressions inside JSX, not statements. You can wrap statements inside an expression. The map callback return value must evaluate to a single value each time (functions can only have a single return value).

function App() {
  const numbers = [1, 2, 3, 4, 5];

  return (
    <div>
      {numbers.map((number) => {
        if (number % 2 === 0) {
          return <h1>{number}</h1>;
        } else {
          return <h2>{number}</h2>;
        }
      })}
    </div>
  );
}

If you try to return a comma-separated list of values from a function only the last value is returned.

function testTheReturn(first, second) {
  return first, second;
}
// only the second argument is returned
console.log(testTheReturn(1, 2)); // 2

An expression evaluates to a single value and a function can only return a single value.


I know it is confusing and I’m probably not explaining it well enough. If you really want to understand JSX I might suggest you try writing React templating using React.createElement.

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.