65

For example could I do:

import React from 'react';
import PanelA from './panelA.jsx';
import PanelB from './panelB.jsx';

React.render( 
  <PanelA />
  <PanelB />, 
  document.body  
);

where React would render:

body
   PanelA
   PanelB

Currently I'm getting the error:

Adjacent JSX elements must be wrapped in an enclosing tag

while transpiling with browserify and babelify

Leonid Beschastny
  • 50,364
  • 10
  • 118
  • 122
Bryan Grace
  • 1,826
  • 2
  • 16
  • 29
  • 6
    Nope, it must be exactly one. Wrap them both in `
    `
    – zerkms Sep 15 '15 at 04:50
  • 2
    FYI, from 0.14 rendering into `document.body` like that will throw a warning (despite it being done in many tutorials), rather select an element by id. https://facebook.github.io/react/blog/2015/09/10/react-v0.14-rc1.html#new-helpful-warnings – David Gilbertson Sep 15 '15 at 07:21
  • @DavidGilbertson I am now aware of the warning.. though where body -> #app, why not just create #app with React........... – Bryan Grace Nov 06 '16 at 19:51
  • @BryanGrace can you please select the right answer for your question? – Pavel Hasala Apr 23 '18 at 16:24
  • Hi, can you please mark the correct answer, as the current one is not true? – Pavel Hasala Jul 19 '19 at 13:49
  • What wasn't obvious to me is that this issue is more general than the question as presented. It occurs not only with two _components_, but also if one of the things being returned is text, e.g. `{myVar}
    ` would still need a wrapper. Furthermore it arises in nested scenarios, e.g. `

    {lines.map(line => ({line}
    ))}

    ` would still need a wrapper even if there was a top-level `

    `. So apparently with any context switch from JavaScript to embedded JSX, the JSX portion must return a single node. See my question https://stackoverflow.com/q/75783783 .

    – Garret Wilson Mar 19 '23 at 19:55

8 Answers8

89

Since the React v16.0 release you can render an array of components without wrapping items in an extra element when you are inside a component:

render() {
  return [
    <li key="one">First item</li>,
    <li key="two">Second item</li>,
    <li key="three">Third item</li>,
    <li key="four">Fourth item</li>,
  ];
}

Remember only to set the keys.

UPDATE

Now from the 16.2 version you can use the Fragments

  render() {
    return (
      <React.Fragment>
        <td>Hello</td>
        <td>World</td>
      </React.Fragment>
    );
  }

Short syntax

  render() {
    return (
      <>
        <td>Hello</td>
        <td>World</td>
      </>
    );
  }

In the ReactDOM.render you still can't render multiple items because react needs a root. So you can render a single component inside the ReactDOM.render and render an array of items in the internal component.

David Ginanni
  • 1,617
  • 15
  • 9
45

React >= 16.2

Since version 16.2 <React.Fragment /> (or <></> for short) was introduced, so you can use conditions.

This is the preferable way.

return (
    <React.Fragment>
        <h1>Page title</h1>
        <ContentComponent />
        {this.props.showFooter && (
            <footer>(c) stackoverflow</footer>
        )}
    </React.Fragment>
)

React 16

Since React 16, you can return from the render() method a list of components. The trade of is you cant easily condition the render and need to add key attribute to each component in the list.

return [
    <h1 key="page-title">Page</h1>,
    <ContentComponent key="content" />,
    <footer>(c)stackoverflow</footer>
]

React < 16

In older versions of React, you can't render multiple components without wrapping them in an enclosing element (tag, component). eg:

return (
  <article>
    <h1>title</h1>
    <meta>some meta</meta>
  </article>
)

If you want to use them realy as just one element, you have to create a module from them.

Pavel Hasala
  • 946
  • 10
  • 14
21

Just wrap your multiple components into single tag. For example:

React.render(
  <div>
    <PanelA />
    <PanelB />
  </div>, 
  document.body  
);
gyzerok
  • 1,338
  • 2
  • 11
  • 26
11

Prior to React 16, multiple top-level elements in the same render() would require you to wrap everything in a parent element (typically a <div>):

render () {
  return (
    <div>
      <Thing1 />
      <Thing2 />
    </div>
  )
}

React 16 introduced the ability to render an array of top-level elements (with a warning that they all must have unique keys):

render () {
  return ([
    <Thing1 key='thing-1' />,
    <Thing2 key='thing-2' />
  ])
}

React 16.2 introduced the <Fragment> element, which functions exactly like the <div> in the first example but doesn't leave a pointless parent <div> hanging around the DOM:

import React, { Fragment } from 'react'

...

render () {
  return (
    <Fragment>
      <Thing1 />
      <Thing2 />
    </Fragment>
  )
}

There's a shorthand syntax for it, but it isn't supported by most tooling (e.g., syntax highlighters) yet:

import React from 'react'

...

render () {
  return (
    <>
      <Thing1 />
      <Thing2 />
    </>
  )
}
gabe
  • 111
  • 2
  • 4
  • Your answer also answered a similar question I had. Also, thank you for pointing out the newest elements in React. This is tremendously helpful to those of us trying to weed through "dated" tutorials and instructional courses. – Cheryl Velez Nov 03 '19 at 12:57
8

If you wish to render multiple components out you need to nest them within one another in order to maintain the Tree-Like structure. This is explained on their docs page for Multiple Components

Ultimately as long as there is one Node at the top level it can work.

You could use just one DOM element such as a <div>

  <div>
    <PanelA />
    <PanelB />
  </div>

However as you create more complex apps and have more interlinking components you may find it best to wrap child components in a parent like so

import React from 'react';
import PanelA from './panelA.jsx';
import PanelB from './panelB.jsx';

var PanelHolder = React.createClass({
  render: function() {
    return (
      <div>
        <PanelA />
        <PanelB />
      </div>
    )
  }
});

And then in your main js file, you would do:

import React from 'react';
import PanelHolder from './panelHolder.jsx';

React.render( 
  <PanelHolder /> 
  document.body  
);
JEV
  • 2,494
  • 4
  • 33
  • 47
2

You can do it like this too.

const list = [item1, item2]
const elements = (
    <div>
      {list.map(element => element)}
    </div>
  );
ReactDOM.render(elements, document.body);
Ankur Kedia
  • 3,453
  • 1
  • 13
  • 15
1
this.propsTextBox.value = this._context.parameters.textBoxProperty.raw || "";
var elements = new Array<React.SFCElement<any>>();
elements.push(React.createElement(
                TextField, 
                this.propsTextBox
            ));
elements.push(React.createElement(
    Label, 
    this.propsLabel
));

ReactDOM.render(
    elements,  
    this._container
);
  • Welcome to the site @Arnaldo. Just a small recommendation: the above snippet could benefit from a brief explanation as to why it solves the problem even if the snippet is fairly self explanatory. – Jeff Mergler Feb 01 '20 at 18:03
0
React.render( 
  <PanelA>
      <PanelB />
  </PanelA> 
  document.body  
);
Ruchi
  • 1
  • 1
    It will be better if you add some explanation. – Trí Phan May 07 '20 at 04:03
  • 1
    While this code may provide a solution to the question, it's better to add context as to why/how it works. This can help future users learn, and apply that knowledge to their own code. You are also likely to have positive feedback from users in the form of upvotes, when the code is explained. – borchvm May 07 '20 at 07:39