Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React <div> cannot appear as a child of <tr> Warning

I am getting the following warnings in a React component:

enter image description here

The related code is the following:

import React, { PropTypes } from 'react';
import { Checkbox } from 'react-bootstrap'; 

const MyComponent = (params) => {

function onSelect(event) {
    params.onSelect(event, params.data.id);
}

return (
    <tr key={params.data.id}>
        {params.isSelectable ? (
            <Checkbox onChange={onSelect}>
                <td>{params.data.firstName}&nbsp;</td>
                <td>{params.data.lastName}&nbsp;</td>
            </Checkbox>
        ) : (
            <div>
                <td>{params.data.firstName}&nbsp;</td>
                <td>{params.data.lastName}&nbsp;</td>
            </div>
        )}
    </tr>
);

};

If I remove the div tags, I get the following error:

Adjacent JSX elements must be wrapped in an enclosing tag

I am new to React, so i am not quite clear on what is going on here. What's the problem and how can I fix it?

Update: my React version is 15.3.2.

like image 204
lukegf Avatar asked Dec 20 '17 17:12

lukegf


2 Answers

If you need to return several elements and can't have a wrapper (such as in this case), you have a new option as of React 16.2. Fragments:

<React.Fragment>
  <td>{params.data.firstName}&nbsp;</td>
  <td>{params.data.lastName}&nbsp;</td>
</React.Fragment>

Or, you might be able to simplify it as:

<>
  <td>{params.data.firstName}&nbsp;</td>
  <td>{params.data.lastName}&nbsp;</td>
</>

The fragments won't resolve to any HTML element, so the <td>s will be direct children of your <tr>.

like image 90
Raicuparta Avatar answered Oct 18 '22 22:10

Raicuparta


There are two problems with your code

  1. Only td and th are allowed inside tr
  2. In React version < 15, you have to wrap tags in one element, when you try to render them. In React 16, you can now do the following :

    [
      <td key={1}>{params.data.firstName}&nbsp;</td>,
      <td key={2}>{params.data.lastName}&nbsp;</td>
    ]
    

    instead of wrapping the tds inside a div

I also suggest you extract your logic outside of the tr

like image 31
Abderrahmane TAHRI JOUTI Avatar answered Oct 18 '22 22:10

Abderrahmane TAHRI JOUTI