How do I render sibling elements without wrapping them in a parent tag?

In most cases, having a parent tag isn't an issue.

React.createClass({
render: function() {
return (
<tbody>
<tr><td>Item 1</td></tr>
<tr><td>Item 2</td></tr>
</tbody>
);
}
});

But there are some cases where it makes sense to have sibling elements in one render function without a parent, and especially in the case of a table, you don't want to wrap a table row in a div.

React.createClass({
render: function() {
return (
<tr><td>Item 1</td></tr>
<tr><td>Item 2</td></tr>
);
}
});

The second example gives the following error: Adjacent XJS elements must be wrapped in an enclosing tag while parsing file.

How can I render two sibling elements without wrapping them in a <div> or something similar?

32278 次浏览

This is a limitation currently, but will likely be fixed at some point in the future (there's some open issues on the github repo).

For now, you can use a function which returns an array (this is basically a stateless component):

function things(arg, onWhatever){
return [
<tr><td>Item 1</td></tr>,
<tr><td>Item 2</td></tr>
];
}

And use that in your component.

return (
<table><tbody>
{things(arg1, this.handleWhatever)}
{things(arg2, this.handleWhatever)}
</tbody></table>
);

Update

In React 16 you will be able to return an array from render.

Another Update

You can now either return a top level array, or use <React.Fragment>.

With an array we need to place a key on each item, as React doesn't know that the two elements are constant, instead of a dynamically created list:

function RowPair() {
return [
<tr key="first"><td>First</td></tr>,
<tr key="second"><td>Second</td></tr>,
]
}

With React.Fragment, it behaves much more like wrapping it in a <div> or similar, where a key isn't required if we're not building the children dynamically. First, we can wrap the array in a Fragment:

function RowPair() {
return <React.Fragment>{[
<tr key="first"><td>First</td></tr>,
<tr key="second"><td>Second</td></tr>,
]}</React.Fragment>
}

And then we can eliminate the array and keys entirely:

function RowPair() {
return <React.Fragment>
<tr><td>First</td></tr>
<tr><td>Second</td></tr>
</React.Fragment>
}

You can wrap it to the brackets like this:

React.createClass({
render: function() {
return (
[
<tr><td>Item 1</td></tr>
<tr><td>Item 2</td></tr>
]
);
}
});

This example is work well for me:

let values = [];


if (props.Values){
values = [
<tr key={1}>
<td>props.Values[0].SomeValue</td>
</tr>
,
<tr key={2}>
<td>props.Values[1].SomeValue</td>
</tr>
];
}


return (
<table className="no-border-table table">
<tbody>
<tr>
<th>Some text</th>
</tr>
{values}
</tbody>
</table>
)

Woohoo! The React team finally added this feature. As of React v16.0, you can do:

render() {
// No need to wrap list items in an extra element!
return [
// Don't forget the keys :)
<tr key="a"><td>Item 1</td></tr>,
<tr key="b"><td>Item 2</td></tr>
];
}

See the full blog post explaining "New render return types: fragments and strings" here.

Something like this syntax worked for me

this.props.map((data,index)=>{return( [ <tr>....</tr>,<tr>....</tr>];)});

For those, who uses TypeScript, the correct syntax is:

return [
(
<div>Foo</div>
),
(
<div>Bar</div>
)
];

I know this has been an old post, but maybe my answer could be a help for newbies like me.

In React 16.2, improved support for Fragments was added.

You can now return it like this:

return (
<>
<tr><td>Item 1</td></tr>
<tr><td>Item 2</td></tr>
</>
);

You can wrap it with <></> or <Fragment></Fragment>.

If you would like to pass some attributes, only key is supported at the time of writing, and you'll have to use <Fragment /> since the short syntax <></> doesn't accept attributes.

Note: If you are going to use the short syntax, make sure that you are using Babel 7.

Source Reference

Having a parent element is helpful in most cases, as for example, you can have a parent className which can target children elements style and a few other scenarios...

But, if you really don't want to do that, you can use React.Fragment

So simply do something like this:

<React.Fragment>
<First />
<Second />
<Third />
</React.Fragment>

From version 16.2, there is a shortened version also using <>, which look like this in render function:

render() {
return (
<>
<First />
<Second />
<Third />
</>
);
}

Also, if using version 16.0 and above, you can return array of elements which doesn't need parent wrapper also like below:

render() {
return [
<h1 key="heading">Hello from Alireza!</h1>,
<p key="first">Here where I'm!</p>,
<p key="second">And again here :)</p>
];
}

We can render two sibling components by wrapping them inside React.Fragment. For e.g.

ReactDOM.render(
<React.Fragment>
<Item1/>
<Item2/>
</React.Fragment>,document.getElementById('root')
);

There is even a shorter hand for this though.

ReactDOM.render(
<>
<Item1/>
<Item2/>
</>,document.getElementById('root')
);

Wrapping the components inside the React.Fragment does not add extra nodes to DOM.