Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

reactjs

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?

like image 614
thealexbaron Avatar asked Feb 06 '15 17:02

thealexbaron


People also ask

How do you render a child component in the parent component?

To pass data from child to parent component in React:Pass a function as a prop to the Child component. Call the function in the Child component and pass the data as arguments. Access the data in the function in the Parent .

Do React fragments need keys?

We no longer need to provide keys, we don't need to add array commas, and we still avoid adding an extraneous DOM element because React. Fragment doesn't become an actual element during rendering. We can import Fragment to avoid having to fully write out React. Fragment .

Can you add a key to a React fragment?

Use the more verbose syntax of fragments to add a key prop to a React fragment, e.g. <React. Fragment key={key}> . The more verbose syntax achieves the same result - groups a list of elements without adding extra nodes to the DOM.


1 Answers

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> } 
like image 144
Brigand Avatar answered Oct 07 '22 05:10

Brigand