How to fix Warning: validateDOMNesting(...): <div> cannot appear as a child of <tbody>

29,937

Solution 1

Most likely the component Spinner renders a <div> as the outermost node. Check the implementation of it.

You implicitly render it inside <tbody> through the lines

<tbody>
    {usersList}
</tbody>

where usersList defaults to <Spinner /> when there are no users or loading is true. This is why get the error.

A fix would be to wrap the Spinner into a td that spans the whole row:

if (users === null || loading) {
    usersList = <tr><td colSpan="4"><Spinner /></td></tr>;
} else {
    // ...
}

Solution 2

validateDOMNesting(...): cannot appear as a child of <div>. I see an error similar to this You replace : tag <body> to <div>

Solution 3

I had the same problem. I had a external spinner component that I needed to inject. This is how i solved it:

<table className="table profit-withdrawal">
    <thead className="thead-default">
        <tr>
            <th>Nick Name</th>
            <th>Transfer to</th>
            <th>Details</th>
            <th>Actions</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <DotsLoaderComponent variant="dark" dimension="large" />
            </td>
        </tr>
        {this.renderTableData()}
    </tbody>
</table>

So I wrapped my spinner component inside a:

<tr>
    <td>YOUR COMPONENT HERE</td>
</tr>

Solution 4

It may not be your case, but it may be someone else's. It's kind of embarrassing but I had this problem because I was importing the wrong component:

import Table from 'react-bootstrap/Col'; <-- Is a Col not a Table

Check if the imports are correct

Share:
29,937
lironzaa
Author by

lironzaa

Updated on July 09, 2022

Comments

  • lironzaa
    lironzaa almost 2 years

    im passing users list as a props to UserItem Component to make iterate on user list and displaying them on table. the list is displayed correctly and i dont have any divs in my render return but i still get the error : index.js:1446 Warning: validateDOMNesting(...): cannot appear as a child of .

    tried many solutions found online but none of them worked

    UsersManagement code :

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    import { connect } from 'react-redux';
    import Spinner from './common/Spinner';
    import { getUsers } from '../actions/userActions';
    import UserItem from './UserItem';
    
    class UsersManagement extends Component {
      componentDidMount() {
        if (!this.props.auth.isAuthenticated) {
          this.props.history.push('/login');
        }
        this.props.getUsers();
      }
    
      render() {
        const { users, loading } = this.props.user;
        let usersList;
        if (users === null || loading) {
          usersList = <Spinner />
        } else {
          if (users.length > 0) {
            usersList = users.map(user => (
              <UserItem key={user._id} user={user} />
            ))
          } else {
            usersList = <h2>No users</h2>
          }
        }
    
        return (
          <div className="row">
            <div className="col-12">
              <h1 className="text-center mb-2">Users Management</h1>
              <button type="button" className="btn btn-success mb-4">New User</button>
              <table className="table">
                <thead>
                  <tr>
                    <th scope="col">Options</th>
                    <th scope="col">Username</th>
                    <th scope="col">Email</th>
                    <th scope="col">Phone Number</th>
                  </tr>
                </thead>
                <tbody>
                  {usersList}
                </tbody>
              </table>
            </div>
          </div>
        )
      }
    }
    
    UsersManagement.propTypes = {
      getUsers: PropTypes.func.isRequired,
      auth: PropTypes.object.isRequired,
      user: PropTypes.object.isRequired
    }
    
    const mapStateToProps = state => ({
      auth: state.auth,
      user: state.user
    })
    
    export default connect(mapStateToProps, {
      getUsers
    })(UsersManagement);
    

    UserItem code :

    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    
    class UserItem extends Component {
      render() {
        const { user } = this.props;
        console.log(user);
        return (
          <tr>
            <th scope="row">
              <button type="button" className="btn btn-primary fa-xs mr-1"><i className="fas fa-pencil-alt"></i></button>
              <button type="button" className="btn btn-danger fa-xs"><i className="far fa-trash-alt"></i></button>
            </th>
            <td>{user.username}</td>
            <td>{user.email}</td>
            <td>{user.phone}</td>
          </tr>
        )
      }
    }
    
    UserItem.propTypes = {
      user: PropTypes.object.isRequired
    }
    
    export default UserItem;
    

    i expect to to fix the warning message

  • lironzaa
    lironzaa about 5 years
    you are correct if i set usersList while fetching the data to null it solves the problem. but now i dont have loading spinner, do you have any idea of to keep the spinner and not get this error?
  • trixn
    trixn about 5 years
    @lironzaa You may want to wrap the Spinner with a tr and a td with colspan set to 4 so that it spans the whole row. This would be valid markup.