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?

99400 次浏览

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>;

The accepted answer wasn't the root cause in my case. I got the same warning when I had a comment after <th> tag. The warning went away when I removed the comment.

const TableHeaders = (props) => (
<tr>
<th>ID</th> {/* TODO: I had a comment like this */}
</tr>
)

EDIT: Removing the space between </th> and {/* will also do the trick.

In addition to @Jarno's answer, I also ran into this issue as well. Double check that you don't have any additional } or { at the end of your javascript code:

{this.props.headers.map(header => <th key={header}>{header}</th>)}}
↑

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>

I received this warning when I had a parenthesis instead of a curly bracket

<table>
<tbody>
<tr>
(showMsg && <td>Hi</td>} // leading '(' should be a '{'
</td>
</tbody>
</table>

Notification warning: validateDOMNesting(...): Whitespace text nodes cannot appear as a child of <tbody>. Make sure you don't have any extra white space between tags on each line of your source code. In my case, initialize variable should NOT is null.

 let elementCart = ''; {/* in the here,warning will append  */}
if(productsCart.length > 0){
elementCart = productsCart.map((item, index) => {
return <CartItem item={item} key={index} index={index} />
});
}


return(
<tbody id="my-cart-body">
{elementCart}
</tbody>
)

Solution: let elementCart = null;

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
}

Incase anyone else comes across this error or a similar whitespace error with Material UI in React, my solution after hours of breaking my code was a simple javascript comment inside of my table.

 { /*  sortable here */ }

I removed that from between my table elements and the warning disappeared.

I received this warning when I put text inside <tr> element with no <td> elements. I wrapped my text with <td> elements and the warning disappeared.

When I did this, having a whitespace in my text or having used {} didn't matter.

In my case I indeed had a <tr> inside a <tr> (intended to use <td>) :)

in my case initialize a variable with null instead of "" works fine

It's very easy to find. Just open your inspect and look for tag. It should appear at the beginning or at the end of the tag a quoted string like this:

Inspect element  on google chrome

A <tr> HTML tag indicates a table row. So, any text to be displayed inside a table row must be placed inside <td> HTML tag. This would remove the error.

Example:

return (
<tr>
<td> {/* Using <td> inside <tr> */}
Hello World!
</td>
</tr>
);

Make sure the let variables are valued otherwise initialize a new empty array.

{headers ? headers : []}


or


{rows || []}

For me it works like a charm ...

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


return (
<table className="table table-hove">
<thead>
<tr>
{headers ? headers : []}
</tr>
</thead>
<tbody>
{rows || []}
</tbody>


</table>
)
}

also || null can solve it. the important is that the value is not ''

Kevin Law (from other comment) said that you can do this:

{
foo ? (<tr><td>{foo}</td></tr>) : null
}

But you can also fix it like this:

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

Removing the comment is what helped me too enter image description here

You shouldn't pass an unexpected element in the table body tag. You should use tr and td

In your rows would return the element with tr and td

{rows}

Something like

return(
<tr>
<td>
Hello
</td>
</tr>
)

For my situation, I was getting this error because I forgot to update a SQL query to include an updated column name. The original query was trying to access a column that didn't exist.

This query was being used with Nextjs, React, Material UI and sent to a PostgreSQL server in order to load up a MUI front-end table with database information from the table.

Updating the query fixed the issue.