React: validateDOMNesting incorrectly validates table children

Created on 24 Apr 2018  路  1Comment  路  Source: facebook/react

Do you want to request a feature or report a bug?

bug

What is the current behavior?

validateDOMNesting shows warning when table element has tr element as a direct child

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than React. Paste the link to your JSFiddle (https://jsfiddle.net/Luktwrdm/) or CodeSandbox (https://codesandbox.io/s/new) example below:

Please find the example copied from MDN (the first HTML example): https://codesandbox.io/s/8z5wyo2.
Open browser's console and run it. In the console you will see warning: validateDOMNesting(...): <tr> cannot appear as a child of <table>. Add a <tbody> to your code to match the DOM tree generated by the browser.

What is the expected behavior?

According to MDN table could have tr as a child (there are such examples on their pages here and here), so I'd expect that warning does not appear

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

The issue is found in v16.x.x in Chrome / FF. It may affect other browsers and prior versions

Most helpful comment

As far as I know the problem isn't that you can't do that in HTML (you can do plenty of things in HTML), but that the browsers will insert a <tbody> DOM node.

In fact that example from MDN shows it. If you look at its code, there's no tbody:

<p>Simple table with header</p>
<table>
  <tr>
    <th>First name</th>
    <th>Last name</th>
  </tr>
  <tr>
    <td>John</td>
    <td>Doe</td>
  </tr>
  <tr>
    <td>Jane</td>
    <td>Doe</td>
  </tr>
</table>

But if you look at the DOM structure, tbody is there:

screen shot 2018-04-24 at 12 23 30 pm

The browser creates a tbody node automatically when parsing HTML.

In the past this used to be an issue for React because it used to do the initial markup insertion by setting innerHTML. So React would set the HTML, and then the browser would insert a tbody node in the middle, confusing and breaking React.

Currently, React doesn't use innerHTML for initial rendering, so this specific problem is gone. It would, however, still be a problem if you use server rendering (and hydrate from HTML), or if React needs to move to using innerHTML in the future again for some reason.

So the warning is valid. Hopefully following it does not present difficulties. :-)

>All comments

As far as I know the problem isn't that you can't do that in HTML (you can do plenty of things in HTML), but that the browsers will insert a <tbody> DOM node.

In fact that example from MDN shows it. If you look at its code, there's no tbody:

<p>Simple table with header</p>
<table>
  <tr>
    <th>First name</th>
    <th>Last name</th>
  </tr>
  <tr>
    <td>John</td>
    <td>Doe</td>
  </tr>
  <tr>
    <td>Jane</td>
    <td>Doe</td>
  </tr>
</table>

But if you look at the DOM structure, tbody is there:

screen shot 2018-04-24 at 12 23 30 pm

The browser creates a tbody node automatically when parsing HTML.

In the past this used to be an issue for React because it used to do the initial markup insertion by setting innerHTML. So React would set the HTML, and then the browser would insert a tbody node in the middle, confusing and breaking React.

Currently, React doesn't use innerHTML for initial rendering, so this specific problem is gone. It would, however, still be a problem if you use server rendering (and hydrate from HTML), or if React needs to move to using innerHTML in the future again for some reason.

So the warning is valid. Hopefully following it does not present difficulties. :-)

Was this page helpful?
0 / 5 - 0 ratings