How To

Fix error – JSX expressions must have one parent element in React

jsx expressions must have one parent element

The React.js error “JSX expressions must have one parent element” occurs when you have a component that returns multiple rendered elements. JSX requires that all your expressions or adjacent jsx elements must be wrapped in an enclosing ‘<div>’ tag or a React fragment ‘<><p></p> <>’ so that it will be return as a single container. First, allow me to explain why this error occurs and how you can fix it?

JSX (JavaScript XML) is a JavaScript extension that makes it possible for developers to use HTML tags directly in JavaScript code. It helps to module the DOM elements that is required to be return from one component to another.

Why does JSX requires all expressions to be wrapped in an enclosing tag? The short answer is that each component needs to return a single value and not two or more. Example of how this error occurs when we return two parent elements…

export default function App() {
  // JSX expressions must have one parent element.
 // we have provided two 
  return (
    <h1>First heading</h1>
    <h2>Second heading</h2>
  );
}

The above JSX will be translated as…

function App() {
  return React.createElement("h1", null, "First heading")
  React.createElement("h2", null, "Second heading")
}
JSX expressions must have one parent element in react

You can see from the JSX translation above that we’re returning two items which is not valid in Vanilla JavaScript and other object-oriented programming languages. You can only return a single item from a components/function and once the item is returned the function execution is terminated. When you want to return a multiple value from a function, you have to wrap it inside an array but not to return each separately (that’s the concept). If the above code was an expression and we’re passing an argument, it will be impossible for the other component to handle such parameters. What you need is to return a single parent element and include child elements in it.

Also, note that when you return an expression directly as shown in below, react will throw an error.

export default function App(){
  return(
    {'Hello world'}
  );
}

How do you solve the above ReactJS error? There’re two ways to fix it, wrap and return all element in a single React-fragment, DIV or another HTML tag.

Below is how you can fix the error “jsx expressions must have one parent element” using the concise syntax of React-fragment.

export default function App() {
  return (
    // wrap all element in react fragment
    <>
    <h1>First heading</h1>
    <h2>Second heading</h2>
    </>
  );
}

The two elements above have all been group in a fragment ‘<> </>’ here, the fragment represent a container with the two elements as it children’s. The main concept here is to make sure that you’re not adding any extra nodes to the DOM. If you do, there will be two or more values needed to be return from the function and that will cause the above error to occur.

If you want, you may also use the verbose syntax of fragments by using “React” and its inner class ‘Fragment” like how an HTML tag is used.

export default function App() {
  return (
    // wrap all element in react fragment
    <React.Fragment>
    <h1>First heading</h1>
    <h2>Second heading</h2>
    </React.Fragment>
  );
}

None, of the above approach is wrong, they all achieve the same result. However, the concise syntax is the most used one it supported by most code editors with VS-CODE (visual studio code) included.  All the elements grouped in the fragment are its children’s and the inner elements can also contain sub-tags.

Also, make sure not to be tempted to return two fragments separately as shown below…

export default function App() {
  return (
    // wrap all element in react fragment
    <>
    <h1>First heading</h1>
    <h2>Second heading</h2>
    </>

  // Wrong
    <>
    <h1>First heading</h1>
    <h2>Second heading</h2>
    </>
  );
}

Check also, how to disable button in angular on condition?

The next solution is to group your child elements in a <div> or another DOM element e.g. a ‘h1’.

export default function App() {
  return (
    <div>
      <h2>JSX CODE</h2>
      <h2>JSX BRACES</h2>
    </div>
  );
}

We now have a 2 <h2> child elements grouped in a <div> parent container. This will solve the error because the component returns a single parent container that contains multiple children. If adding a ‘div’ or other element will break your application layout, then safely use fragment because it does not add extra markup to the DOM.

When working with conditions in JSX, you will be presented with an expression error if you return multiple elements in one of the code paths at the same level. For example, if the condition is true, and you return 3 elements without grouping it in a parent container.

export default function App() {
  return (
    <div>
      {/* JSX expressions must have one parent element.ts(2657) */}
      {true ? (
        <h2>ReactJS tutorials</h2>
        <h2>Typescript</h2>
        <h2>JavaScript</h2>
      ) : null}
    </div>
  );
}

We have used ternary operator in the above code but you can see that the truthy path (the code that comes before the ‘?’ operator) returns 3 elements at the same level which will lead to an error. A workaround is to group the elements in a fragment or a div depending on your layout.

export default function App() {
  return (
    <div>
      {true ? (
        <>
        <h2>ReactJS tutorials</h2>
        <h2>Typescript</h2>
        <h2>JavaScript</h2>
        </>
      ) : null}
    </div>
  );
} 

This will fix the error, the truthy code-path now returns a single element as it value. You have to note that React components are just functions that returns a value. And you cannot return multiple values in a function at the same time, doing so will cause the error “JSX expressions must have one parent element.”  You either have to wrap it in an object or an array. If you want to see an example of wrapping elements in an array, then below is how it works.

export default function App() {
  return [<h3 key={0}>Hello</h3>, <h3 key={1}>World</h3>];
}

This will solve the error because everything is returned as an array which is a single value and it represent the parent element. But can you spot the extra work we did? We have to pass a unique ‘key’ prop as an attribute to each child element. If you fail to do that React will throw the error “should have a unique key prop” This will be a lot of work if we have 1000 elements to render. Fragment is more intuitive and readable, why not use it to make your life easy instead of the above unnecessary key array syntax?

export default function App() {
  return (
    <>
      <h2>Hello</h2>
      <h2>World</h2>
    </>
  );
}

Check also, How long it takes to learn JavaScript or ReactJS to get a job?

Question, ‘<div>’ and react fragment ‘<> </>’ which one should you use to solve the above error – JSX expressions must have one parent element?

One main significant of using fragment to solve the above error comes when we need not to wrap some elements in a container due to our application requirement. Ask yourself, what would you do if one of your components requires different element instead of an element grouped in a single container? For example, if component B renders <UL> or <OL> and it needs component A to render list of <li> and return to it. What will you do? You have to group the list of <li> tags in a <div> or return different list of <li> right? Wrong, that will be syntactically invalid because that’s not what the receiving component requires and if you return list of <li> it will throw the above error. Take a look at below react-code

export default function App(){

  const ReturnManyLI = () => {
  // this will throw JSX expression error
    return(
      <li>Java programing language</li>
      <li>C++</li>
      <li>C#</li>
    )
  }

  return(
    <div>
      <ul>
        <li>JavaScript</li>
        < ReturnManyLI />
      </ul>
    </div>
  );
}

The above ‘ReturnManyLI’ component will throw an error when you run the application. Because we’re returning different elements without it being enclosed in a parent element. Also, within the last return expression above, the rendering of the ‘ReturnManyLI’ will not work even if the above error is overridden and the application successfully execute. Why because there won’t be any element returned, so definitely it will throw a second error. What if we wrap all the <li> in parent <div> tag? The above error will not be thrown but we will get syntactical invalid error, because <div> tags should not be used as a child element of <UL> or <OL>.

The solution to the above problem is to use <React.Fragment> or ‘<> </>’ component. If you want to enclose list of elements without rendering the parent container on the DOM, then fragment is what you need. So, let me show you how you can use it to solve above example…

export default function App(){

  const ReturnManyLI = () => {
    return(
      <React.Fragment> // or simply use <>
      <li>Java programing language</li>
      <li>C++</li>
      <li>C#</li>
      </React.Fragment> // or </>
    )
  }

  return(
    <div>
      <ul>	
        <li>JavaScript</li>
        < ReturnManyLI />
      </ul>
    </div>
  );
}

Does JSX need to be in parentheses? Yes, when working with conditions using ternary operators, it better to wrap all your parent container in a parenthesis. This makes your code clean and easy to debug doing code review.

export default function App() {
  return (
    <div>
      {true ? (
        <>
        <h2>first true tag</h2>
        <h2>second true tag</h2>
        </>
      ) : 
      (
     <h2>false tag</h2>
      )
    }
    </div>
  );
} 
Tagged

About Justice Ankomah

computer science certified technical instructor. Who is interested in sharing (Expert Advice Only)
View all posts by Justice Ankomah →

Leave a Reply

Your email address will not be published. Required fields are marked *