Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React: validateDOMNesting: #text cannot appear as a child of <tr>

Can you explain me why react show warning Warning: validateDOMNesting(...): #text cannot appear as a child of <tr>. See Router > RouterContext > CarWashPage > AllCarWashTable > tr > #text.? I don't see any text inside tag tr

Code that renders table

export default class AllCarWashTable extends React.Component{

constructor(props) {
    super(props);
    this.generateHeaders = this.generateHeaders.bind(this);
    this.generateRows = this.generateRows.bind(this);
};

static propTypes = {
    cols : React.PropTypes.array.isRequired,
    rows : React.PropTypes.array.isRequired
}

generateHeaders() {
    let cols = this.props.cols;  // [{key, label}]
    return cols.map(function(colData) {
        return <th key={colData.key}> {colData.label} </th>;
    });
}

generateRows() {
    let cols = this.props.cols,  // [{key, label}]
        data = this.props.rows;
    if (this.props.rows.length > 0) {
        return data.map(function(item) {
            var cells = cols.map(function(colData) {
                return <td key={colData.key}> {item[colData.key]} </td>;
            });
            return <tr key={item.id}> {cells} </tr>;
        });
    }
}

render(){
    let headers = this.generateHeaders();
    let rows = this.generateRows();

    return (
         <table className="table table-hove">
             <thead>
                <tr>
                    {headers}
                </tr>
             </thead>
             <tbody>
                    {rows}
             </tbody>

         </table>
    )
}
}

At the end, my table has the following structure

enter image description here

Where is the problem?

like image 738
Bizon4ik Avatar asked Oct 07 '16 09:10

Bizon4ik


3 Answers

The problem is the spaces in this line:

return <tr key={item.id}> {cells} </tr>;

It might seem silly, but you're actually rendering the cells and some whitespace (i.e. text). It should look like this:

return <tr key={item.id}>{cells}</tr>;
like image 193
tobiasandersen Avatar answered Nov 13 '22 23:11

tobiasandersen


This will also happens when using logical AND short-circuit && to show/hide conditional rows:

{
  foo && (<tr><td>{foo}</td></tr>)
}

change it to ternary a ? b : c form where c is null will fix it

{
  foo ? (<tr><td>{foo}</td></tr>) : null
}
like image 83
Kevin Law Avatar answered Nov 14 '22 01:11

Kevin Law


In my case where was an empty '' output (w\o space inside)

<tbody>
  {this.props.orders.map(
    order =>this.props.selectedAgent === order.agent ? 
      <Row item={order} key={ order._id } /> : ''
    )
  }
</tbody>

The null does the trick:

<tbody>
  {this.props.orders.map(
    order =>this.props.selectedAgent === order.agent ? 
      <Row item={order} key={ order._id } /> : null
    )
  }
</tbody>
like image 30
northernwind Avatar answered Nov 14 '22 01:11

northernwind