javascript 反应:渲染期间 array.map 中的多个表行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/47756703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 07:34:35  来源:igfitidea点击:

React: Multiple table rows in array.map during render

javascriptreactjshtml-table

提问by BluePrint

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 errorwhich I already knew but tried anyway.

当我尝试上述方法时。删除 div 给了我Syntax error我已经知道但无论如何都尝试过的。

Does anyone have an idea how to solve this?

有谁知道如何解决这个问题?

回答by Jo?o Cunha

You're doing

你在做

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

that prints falselike <tr>false</tr>if mobile_open is false.

打印false就像<tr>false</tr>mobile_open 是 false 一样。

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 Fragment Syntax

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

更多关于这里的片段

回答by Stuart Casarotto

In React16you 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>

回答by mb21

This says it all: <div> cannot appear as a child of <tbody>

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

In myList.map(f), fshould return exactly one <tr>each time it's called. So you could preprocess myListto contain JSON items than can then be rendered as you wish.

myList.map(f),每次调用时都f应该返回一个<tr>。因此,您可以进行预处理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 divinside the <td>when you click your arrow icon?

但是,最好为您拥有的每个数据项输出一行,并以不同的方式显示附加信息。当您单击箭头图标时,也许在div里面插入一个<td>