[javascript] Parse Error: Adjacent JSX elements must be wrapped in an enclosing tag

The problem

Parse Error: Adjacent JSX elements must be wrapped in an enclosing tag

This means that you are trying to return multiple sibling JSX elements in an incorrect manner. Remember that you are not writing HTML, but JSX! Your code is transpiled from JSX into JavaScript. For example:

render() {
  return (<p>foo bar</p>);
}

will be transpiled into:

render() {
  return React.createElement("p", null, "foo bar");
}

Unless you are new to programming in general, you already know that functions/methods (of any language) take any number of parameters but always only return one value. Given that, you can probably see that a problem arises when trying to return multiple sibling components based on how createElement() works; it only takes parameters for one element and returns that. Hence we cannot return multiple elements from one function call.


So if you've ever wondered why this works...

render() {
  return (
    <div>
      <p>foo</p>
      <p>bar</p>
      <p>baz</p>
    </div>
  );
}

but not this...

render() {
  return (
    <p>foo</p>
    <p>bar</p>
    <p>baz</p>
  );
}

it's because in the first snippet, both <p>-elements are part of children of the <div>-element. When they are part of children then we can express an unlimited number of sibling elements. Take a look how this would transpile:

render() {
  return React.createElement(
    "div",
    null,
    React.createElement("p", null, "foo"),
    React.createElement("p", null, "bar"),
    React.createElement("p", null, "baz"),
  );
}

Solutions

Depending on which version of React you are running, you do have a few options to address this:

  • Use fragments (React v16.2+ only!)

    As of React v16.2, React has support for Fragments which is a node-less component that returns its children directly.

    Returning the children in an array (see below) has some drawbacks:

    • Children in an array must be separated by commas.
    • Children in an array must have a key to prevent React’s key warning.
    • Strings must be wrapped in quotes.

    These are eliminated from the use of fragments. Here's an example of children wrapped in a fragment:

    render() {
      return (
        <>
          <ChildA />
          <ChildB />
          <ChildC />
        </>
      );
    }
    

    which de-sugars into:

    render() {
      return (
        <React.Fragment>
          <ChildA />
          <ChildB />
          <ChildC />
        </React.Fragment>
      );
    }
    

    Note that the first snippet requires Babel v7.0 or above.


  • Return an array (React v16.0+ only!)

    As of React v16, React Components can return arrays. This is unlike earlier versions of React where you were forced to wrap all sibling components in a parent component.

    In other words, you can now do:

    render() {
      return [<p key={0}>foo</p>, <p key={1}>bar</p>];
    }
    

    this transpiles into:

    return [React.createElement("p", {key: 0}, "foo"), React.createElement("p", {key: 1}, "bar")];
    

    Note that the above returns an array. Arrays are valid React Elements since React version 16 and later. For earlier versions of React, arrays are not valid return objects!

    Also note that the following is invalid (you must return an array):

    render() {
      return (<p>foo</p> <p>bar</p>);
    }
    

  • Wrap the elements in a parent element

    The other solution involves creating a parent component which wraps the sibling components in its children. This is by far the most common way to address this issue, and works in all versions of React.

    render() {
      return (
        <div>
          <h1>foo</h1>
          <h2>bar</h2>
        </div>
      );
    }
    

    Note: Take a look again at the top of this answer for more details and how this transpiles.

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to reactjs

Error: Node Sass version 5.0.0 is incompatible with ^4.0.0 TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received type undefined raised when starting react app Template not provided using create-react-app How to resolve the error on 'react-native start' Element implicitly has an 'any' type because expression of type 'string' can't be used to index Invalid hook call. Hooks can only be called inside of the body of a function component How to style components using makeStyles and still have lifecycle methods in Material UI? React Hook "useState" is called in function "app" which is neither a React function component or a custom React Hook function How to fix missing dependency warning when using useEffect React Hook? Unable to load script.Make sure you are either running a Metro server or that your bundle 'index.android.bundle' is packaged correctly for release

Examples related to render

Django - Reverse for '' not found. '' is not a valid view function or pattern name How to Call a Function inside a Render in React/Jsx Scroll to the top of the page after render in react.js Parse Error: Adjacent JSX elements must be wrapped in an enclosing tag Render HTML to an image