Using react
and react-dom
v0.14.3
.
Have a component which renders:
<table style={tableStyle}>
<tr style={rowStyle}>
<td style={leftColumnStyle}>Battery</td>
<td><StatsBar/></td>
</tr>
...
</table>
Getting an error message in console:
Warning: validateDOMNesting(...): <tr> cannot appear as a child of <table>. See ProductDetails > table > tr. Add a <tbody> to your code to match the DOM tree generated by the browser.
Any ideas why?
Just do what the warning suggests:
<table style={tableStyle}>
<tbody>
<tr style={rowStyle}>
<td style={leftColumnStyle}>Battery</td>
<td><StatsBar/></td>
</tr>
</tbody>
</table>
Browsers need the <tbody>
tag. If it is not in your code, then the browser will automatically insert it. This will work fine on first render, but when the table gets updated, then the DOM tree is different from what React expects. This can give strange bugs, therefore React warns you to insert the <tbody>
. It is a really helpful warning.
Ah makes sense. Problem solved, thanks.
I am facing same issue , please look at this image
the is the code :
import* as React from 'react';
interface IDataTunel {
data: SEmployee[];
}
class SEmployee {
public firstname: string;
public lastname: string;
public id: number;
public fullname: string;
public enrollmentdate: Date;
}
export class EmployeesTemplate extends React.Component<IDataTunel, {}> {
public constructor() {
super();
}
public render() {
return (
<div className="employee-list">
<table className='table'>
<thead>
<tr>
<th>Id</th>
<th>First Name</th>
<th>Last Name</th>
<th>Full Name</th>
<th>Enrollment Date</th>
</tr>
</thead>
<tbody>
{this.props.data.map(({ id, firstname, lastname, fullname, enrollmentdate}) =>
<tr key={id}>
<td>{id}</td>
<td>{firstname}</td>
<td>{lastname}</td>
<td>{fullname}</td>
<td>{enrollmentdate}</td>
</tr>
)}
</tbody>
</table>
</div>);
}
}
export default EmployeesTemplate
{
}
@sophiebits Can this issue be reopened?
The W3C tutorial series for accessible data tables (which are fully compliant with the WCAG 2.0 standards) makes no mention of <tbody>
or <thead>
elements in any of their examples.
Further, if you look at some of their examples showing how to prepare tables with irregular and multi-level headers, you'll see that the use of <tbody>
and/or <thead>
actually becomes a _hindrance_ to making tables fully accessible.
Please, please consider re-evaluating this warning.
@dsifford React is warning because browsers bring it anyway so wouldn't it be a browser issue?
@dsifford Even though those examples don't use tbody, you can/should wrap tbody around all of the tr
elements (col and colgroup live outside). Browsers will insert one if you don't provide it so it is identical from an accessibility perspective. It's because browsers will insert one that we have this warning โ if the browser inserts one and React doesn't expect it, React will get confused. At the time this warning was added we concluded that encouraging people to manually add the tbody would be a simpler fix than teaching React to special-case this one tag. It's possible we could change it but in any event it wouldn't be trivial to implement so I wouldn't expect to see this anytime soon unless you'd like to contribute a fix yourself.
Thanks for the detailed reply @sophiebits!
I'm not at all questioning your knowledge on this subject, since it's unquestionably much deeper than mine. But if I could bother you to explain what you mean by...
Browsers will insert one if you don't provide it so it is identical from an accessibility perspective. It's because browsers will insert one that we have this warning โ if the browser inserts one and React doesn't expect it, React will get confused.
Are you referring to a subset of common browsers? Looking specifically at Chrome 68.0.3440.7
, it doesn't appear that this is happening. Is this something that is done during the render phase and not actually applied in the browsers' visible HTML?
Re: "It's possible we could change it but in any event it wouldn't be trivial to implement so I wouldn't expect to see this anytime soon unless you'd like to contribute a fix yourself."
I'd potentially be willing to contribute a fix to this behavior if I first received the team's blessing that it would be considered. I'd hate to put in a bunch of work on this only to find that it's not something that you guys and gals think fits the project's roadmap.
Speaking directly to a potential fix for this: In my mind, the change could be to instead require a "scope" attribute for all <th>
elements. Unless I'm overlooking something huge, I think that would cover the exact same accessibility issues that are currently covered with the <tbody>
and <thead>
requirements, _and_ allow for irregular and multi-level headers.
Anyway, regardless of your response, thanks so much for your kind response and clarification! And thanks for all you do and continue to do on the React project :smile:
Are you referring to a subset of common browsers? Looking specifically at Chrome 68.0.3440.7, it doesn't appear that this is happening. Is this something that is done during the render phase and not actually applied in the browsers' visible HTML?
Interesting, it looks like you're right. It's not inserting a tbody
tag automatically. If you use renderToString
to insert markup using innerHTML
it does insert the tbody
tag. I tested this in latest Chrome, Firefox and Safari and it seems consistent.
@sophiebits has this been revisited since React started using DOM APIs instead of generating string markup?
I find this warning to be hostile to junior developers.
I think it is ok for a novice to assume any HTML that passes W3C markup validation is acceptable markup. Is it then reasonable to assume that react can consume any valid markup?
When react throws:
<tr>
cannot appear as a child of<table>
It is confusing, is a stumble, and anything that hurts the developer experience should be considered a bug.
I agree it would be better if tr
could appear as a direct child of table
, but it's nontrivial to implement. In lieu of that, that's why we include this text in the warning:
Add a \
Just do what the warning suggests:
<table style={tableStyle}> <tbody> <tr style={rowStyle}> <td style={leftColumnStyle}>Battery</td> <td><StatsBar/></td> </tr> </tbody> </table>
Browsers need the
<tbody>
tag. If it is not in your code, then the browser will automatically insert it. This will work fine on first render, but when the table gets updated, then the DOM tree is different from what React expects. This can give strange bugs, therefore React warns you to insert the<tbody>
. It is a really helpful warning.It helped. Thanks!
๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐๐
Was this page helpful?0 / 5 - 0 ratingsRelated issues
DimitarChristoff ยท 3Comments
MoOx ยท 3Comments
jmullo ยท 3Comments
zpao ยท 3Comments
zpao ยท 3Comments
Most helpful comment
Just do what the warning suggests:
Browsers need the
<tbody>
tag. If it is not in your code, then the browser will automatically insert it. This will work fine on first render, but when the table gets updated, then the DOM tree is different from what React expects. This can give strange bugs, therefore React warns you to insert the<tbody>
. It is a really helpful warning.