简体   繁体   English

React:渲染期间array.map中的多个表行

[英]React: Multiple table rows in array.map during render

I have this problem. 我有这个问题。 I want to loop an array and display the values as a table where each element is a row in the table. 我想循环一个数组并将值显示为一个表,其中每个元素都是表中的一行。 So far, no problems. 到目前为止,没有问题。 But depending on a value in each element, I want to show an additional row with more values for each array element. 但是根据每个元素中的值,我想为每个数组元素显示一个具有更多值的附加行。 I have this code: 我有这个代码:

<tbody>
  {myList.map((item, i) => {
    return (
      <div>
        <tr key={i} onClick={toggleMobileOpen.bind(this, i)}>
          <td className="toggler">
            {item.mobile_open && <ArrowUp />}
            {!item.mobile_open && <ArrowDown />}
          </td>
          <td>{item.elem_one}</td>
          <td>{item.elem_two}</td>
          <td>{item.elem_three}</td>
        </tr>
        {item.mobile_open &&
          <tr className="test-td">
            <td>...</td>
          </tr>
        }
      </div>
    );
  })}
</tbody>

My problem is that I get: 我的问题是我得到:

Warning: validateDOMNesting(...): Text nodes cannot appear as a child of <tr>. 警告:validateDOMNesting(...):文本节点不能显示为<tr>的子节点。

and

Warning: validateDOMNesting(...): <div> cannot appear as a child of <tbody> 警告:validateDOMNesting(...):<div>不能作为<tbody>的子项出现

When I try the above approach. 当我尝试上述方法时。 Removing the div gives me Syntax error which I already knew but tried anyway. 删除div给了我Syntax error ,我已经知道但无论如何都尝试过。

Does anyone have an idea how to solve this? 有谁知道如何解决这个问题?

You're doing 你在做

{item.mobile_open &&
          <tr className="test-td">
            <td>...</td>
          </tr>
        }

that prints false like <tr>false</tr> if mobile_open is false. 如果mobile_open为false,则打印错误,<tr>false</tr>

try 尝试

{item.mobile_open ?
              (<tr className="test-td">
                <td>...</td>
              </tr>) : null
            }

As for the div warning consider using React 16 Fragments 至于div警告,请考虑使用React 16 Fragments

using React 16.0 fragment syntax 使用React 16.0片段语法

<tbody>
  {myList.map((item, i) => {
    return [
        <tr key={i} onClick={toggleMobileOpen.bind(this, i)}>
          <td className="toggler">
            {item.mobile_open && <ArrowUp />}
            {!item.mobile_open && <ArrowDown />}
          </td>
          <td>{item.elem_one}</td>
          <td>{item.elem_two}</td>
          <td>{item.elem_three}</td>
        </tr>,
        {item.mobile_open &&
          <tr className="test-td">
            <td>...</td>
          </tr>
        }

    ];
  })}
</tbody>

But I prefer the most recent React 16.2 Fragment Syntax 但我更喜欢最新的React 16.2片段语法

import React, { Fragment } from "react";

<tbody>
      {myList.map((item, i) => {
        return (
          <Fragment>
            <tr key={i} onClick={toggleMobileOpen.bind(this, i)}>
              <td className="toggler">
                {item.mobile_open && <ArrowUp />}
                {!item.mobile_open && <ArrowDown />}
              </td>
              <td>{item.elem_one}</td>
              <td>{item.elem_two}</td>
              <td>{item.elem_three}</td>
            </tr>
            {item.mobile_open &&
              <tr className="test-td">
                <td>...</td>
              </tr>
            }
          </Fragment>
        );
      })}
    </tbody>

More on fragments here 更多关于碎片的信息

In React16 you are now able to return an array of components allowing you to remove the <div /> . React16中,您现在可以返回一组组件,允许您删除<div />

The code would look something like : 代码看起来像:

 <tbody>
      {myList.map((item, i) => {
        return [
            <tr key={i} onClick={toggleMobileOpen.bind(this, i)}>
              <td className="toggler">
                {item.mobile_open && <ArrowUp />}
                {!item.mobile_open && <ArrowDown />}
              </td>
              <td>{item.elem_one}</td>
              <td>{item.elem_two}</td>
              <td>{item.elem_three}</td>
            </tr>,

            //This inline conditional makes it weird but this works
            ...[item.mobile_open &&
              <tr className="test-td">
                <td>...</td>
              </tr>
            ]
        ];
      })}
    </tbody>

This says it all: <div> cannot appear as a child of <tbody> 这说明了一切: <div> cannot appear as a child of <tbody>

In myList.map(f) , f should return exactly one <tr> each time it's called. myList.map(f)f每次调用时都应该返回一个<tr> So you could preprocess myList to contain JSON items than can then be rendered as you wish. 因此,您可以预处理myList以包含JSON项,然后可以根据需要进行呈现。

However, it's probably better to output one row for each data item you have, and display the additional information in a different way. 但是,为每个数据项输出一行可能更好,并以不同的方式显示其他信息。 Maybe insert a div inside the <td> when you click your arrow icon? 当你点击箭头图标时,可能在<td>插入一个div

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM