警告:validateDOMNesting(...):不能作为以下项的子项出现

时间:2019-01-29 09:24:29

标签: reactjs

我正在尝试使用reactjs进行这种工作。但是它返回错误 <table> cannot appear as a child of <tr>

这是我的RoomRow.js

import React from 'react'
import {Link} from 'react-router-dom'
import { formatAssetName, dailyBookings, bookingArray } from '../helpers/rooms'

// Accept the 24 hour dayHours array as the day's booking data for a room
const rowMapper = (dayHours, props) => {
  let tableRow = []

  // Loop through each hour from 8AM to 9PM (starting at 8AM = 0)
  for (var i = 0; i < 13; i++) {
    // Extract the corresponding data from the 24 hour array
    let bookingData = dayHours[i + 8]

    // If the data for that hour is a number (not a booking object), there is no booking
    // Add a <td> element that indicates the time slot is available
    if (typeof bookingData == 'number') {
      tableRow.push(<td className="table__cell--available" key={bookingData}>
          <Link to="/createbooking" onClick={() => {
              props.onSetRoom(props.room._id)
        }} className="table__link--available">
            &nbsp;
          </Link>
        </td>)

     // If the data is an array, there are two booking objects
    } else if (Array.isArray(bookingData)){

    // Determine which of the two bookings comes first and second
    let firstBookingData = bookingData[0].firstHalfHour ?
      bookingData[0] : bookingData[1]

    let secondBookingData = bookingData[0].secondHalfHour ?
        bookingData[0] : bookingData[1]

      tableRow.push(
        <table className="table--booking--split" key={bookingData}>
          <tbody>
            <tr>
              <td className={`table__cell`}>
                <span
                  onClick={() => props.onShowBooking(firstBookingData)}
                  className={`table__cell--booked table__cell--${firstBookingData.businessUnit // Class name will show the business unit that made the booking, and whether the <td> element should be fully shaded, or half shaded (indicating a half-hour booking)
                    .replace(/ /g, '-')
                    .toLowerCase()}
                  `}
                >
                  &nbsp;
                </span>
              </td>
              <td className={`table__cell`}>
                <span
                  onClick={() => props.onShowBooking(secondBookingData)}
                  className={`table__cell--booked table__cell--${secondBookingData.businessUnit // Class name will show the business unit that made the booking, and whether the <td> element should be fully shaded, or half shaded (indicating a half-hour booking)
                    .replace(/ /g, '-')
                    .toLowerCase()}
                  `}
                >
                  &nbsp;
                </span>
              </td>
            </tr>
          </tbody>
        </table>
      )

    // If there is a booking object, add a <td> element with custom class name to enable stlying
    } else {
      tableRow.push(
        <td className={`table__cell`}>
          <span
            onClick={() => props.onShowBooking(bookingData)}
            className={`table__cell--booked table__cell--${bookingData.businessUnit // Class name will show the business unit that made the booking, and whether the <td> element should be fully shaded, or half shaded (indicating a half-hour booking)
              .replace(/ /g, '-')
              .toLowerCase()}
            ${bookingData.firstHalfHour ? 'table__cell--first-half-hour' : ''}
            ${
              bookingData.secondHalfHour ? 'table__cell--second-half-hour' : ''
            }`}
          >
            &nbsp;
          </span>
        </td>
      )
    }
  }
  return tableRow
}

const RoomRow = props => (
  <tr className="table__row">
    <th scope="row" className="table__cell--align-left">
      <Link to="/createbooking" onClick={() => props.onSetRoom(props.room._id)} className="table__link">{props.room.name}</Link>
      <ul >
      {Object.keys(props.room.assets).map(
        asset =>
          props.room.assets[asset] && (
            <li key={asset} onClick={props.onShowBooking} className="table__data--asset">{formatAssetName(asset)}</li>
            )
          )}
      </ul>
    </th>
    {rowMapper(
      bookingArray(dailyBookings(props.date, props.bookings)),
      props
    )}
  </tr>
)

export default RoomRow

这是我的RoomsList.js

import React from 'react'
import RoomRow from './RoomRow'
import { roomSorter } from '../helpers/sorter'

const RoomsList = props => (
  <table className="table">
    <tbody>
      <tr className="table__row table__row--header">
        <th scope="colgroup" colSpan="15" className="table__cell--header table__cell--level table__cell--align-left">
          Level Eight
      </th>
      </tr>
      <tr className="table__row table__row--subheader">
        <th scope="col" className="table__cell--header table__cell--align-left">
          Room
      </th>
        <th scope="col" className="table__cell--header">
          8am
      </th>
        <th scope="col" className="table__cell--header">
          9am
      </th>
        <th scope="col" className="table__cell--header">
          10am
      </th>
        <th scope="col" className="table__cell--header">
          11am
      </th>
        <th scope="col" className="table__cell--header">
          12pm
      </th>
        <th scope="col" className="table__cell--header">
          1pm
      </th>
        <th scope="col" className="table__cell--header">
          2pm
      </th>
        <th scope="col" className="table__cell--header">
          3pm
      </th>
        <th scope="col" className="table__cell--header">
          4pm
      </th>
        <th scope="col" className="table__cell--header">
          5pm
      </th>
        <th scope="col" className="table__cell--header">
          6pm
      </th>
        <th scope="col" className="table__cell--header">
          7pm
      </th>
        <th scope="col" className="table__cell--header">
          8pm
      </th>
      </tr>
    </tbody>
    <tbody className="table__body">
      {props.rooms &&
        roomSorter(props.rooms, '8').map((room, i) => (
          <RoomRow key={i}
            key={room._id}
            room={room}
            bookings={room.bookings}
            date={props.date === null ? new Date() : props.date}
            onShowBooking={props.onShowBooking}
            onSetRoom={props.onSetRoom}
          />
        ))}
    </tbody>
    <tbody>
      <tr className="table__row table__row--header">
        <th scope="colgroup" colSpan="15" className="table__cell--header table__cell--level table__cell--align-left">
          Level Thirteen
      </th>
      </tr>
      <tr className="table__row table__row--subheader">
        <th scope="col" className="table__cell--header table__cell--width table__cell--align-left">
          Room
      </th>
        <th scope="col" className="table__cell--header">
          8am
      </th>
        <th scope="col" className="table__cell--header">
          9am
      </th>
        <th scope="col" className="table__cell--header">
          10am
      </th>
        <th scope="col" className="table__cell--header">
          11am
      </th>
        <th scope="col" className="table__cell--header">
          12pm
      </th>
        <th scope="col" className="table__cell--header">
          1pm
      </th>
        <th scope="col" className="table__cell--header">
          2pm
      </th>
        <th scope="col" className="table__cell--header">
          3pm
      </th>
        <th scope="col" className="table__cell--header">
          4pm
      </th>
        <th scope="col" className="table__cell--header">
          5pm
      </th>
        <th scope="col" className="table__cell--header">
          6pm
      </th>
        <th scope="col" className="table__cell--header">
          7pm
      </th>
        <th scope="col" className="table__cell--header">
          8pm
      </th>
      </tr>
    </tbody>
    <tbody className="table__body">
      {props.rooms &&
        roomSorter(props.rooms, '13').map((room, i) => (
          <RoomRow key={i}
            key={room._id}
            room={room}
            bookings={room.bookings}
            date={props.date === null ? new Date() : props.date}
            onShowBooking={props.onShowBooking}
            onSetRoom={props.onSetRoom}
          />
        ))
      }
    </tbody>
  </table>
)

export default RoomsList

错误是

index.js:2177 Warning: validateDOMNesting(...): <table> cannot appear as a child of <tr>.
    in table (at RoomRow.js:36)
    in tr (at RoomRow.js:90)
    in RoomRow (at RoomsList.js:61)
    in tbody (at RoomsList.js:58)
    in table (at RoomsList.js:6)

如何解决此错误?

2 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

该错误是明确的。您不能嵌套表。但是,您可以使用colspanrowspan模拟它。

示例:

<table border="1" cellpadding="5">
<tr>
  <td rowspan="2">table cell</td>
  <td>sub table cell</td>
  <td>sub table cell</td>
</tr>
<tr>
  <td>sub table cell</td>
  <td>sub table cell</td>
</tr>
<tr>
  <td>table</td>
  <td colspan="2">table cell</td>
</tr>
<tr></tr>
</table>