首页 > 解决方案 > 为有孩子的对象生成表格行

问题描述

我试图以表格格式显示一堆对象。如果该对象有一个孩子,我希望它显示在下一行中,然后继续向下排列到下一个对象。

在下面的示例中,我成功呈现了一个显示所有顶级或父对象的表格:

const renderCategories = (categories) => {
            let myCategories = [];
            for(let category of categories){
                myCategories.push(
                    <tr key={category.name}>
                        <td><input type="checkbox"></input></td>
                        <td>{category.name}</td>
                    </tr>
                );
            }

            return myCategories;
    }

    return(
      <div>
        <table>
          <thead>
            <tr>
              <th><input type="checkbox"></input></th>
              <th>Name</th>
            </tr>
          </thead>
          <tbody>
            {renderCategories(category.categories)}
          </tbody>
        </table>
      </div>
    )
};

在我的原始版本中,我没有使用表格,而是使用列表,因此通过执行以下操作实现了我想要的:

const renderCategories = (categories) => {
                let myCategories = [];
                for(let category of categories){
                    myCategories.push(
                        <li key={category.name}>
                          {category.name}
                          {category.children.length > 0 ? 
                            {<ul>renderCategories(category.children)}</ul>) : null}
                        </li>
    
                    );
                }
    
                return myCategories;
        }

该解决方案显然不适用于我的新用例,因为我无法在表格行中呈现表格行。这让我发疯,因为似乎没有其他选择。我可以使用 div 而不是表格来实现我想要的设计。但是我想使用一张桌子,或者至少知道如何使用一张桌子来做到这一点。

谁能指出我正确的方向?谢谢

标签: javascriptreactjshtml-tablejsx

解决方案


使用Array.flatMap()和数组展开返回一个扁平的<tr>元素数组。

注意:我还使用level和空<td>元素添加了缩进。您删除该Array.from()行,level如果不需要。

const renderCategories = (categories, level = 0) => 
  categories.flatMap(({ name, children }) => {
    const cat = (
      <tr key={name}>
        <td><input type="checkbox"></input></td>
        {Array.from({ length: level }, (_, i) => <td key={i}></td>)}
        <td>{name}</td>
      </tr>
    );
    
    return children.length ?
      [cat, ...renderCategories(children, level + 1)]
      :
      cat;
  });
  
const Demo = ({ categories }) => (
  <div>
    <table>
      <thead>
        <tr>
          <th><input type="checkbox"></input></th>
          <th>Name</th>
        </tr>
      </thead>
      <tbody>
        {renderCategories(categories)}
      </tbody>
    </table>
  </div>
);

const categories = [{ name: 'A', children: [{ name: 'A1', children: [] }, { name: 'A2', children: [] }] }, { name: 'B', children: [{ name: 'B1', children: [{ name: 'B1-1', children: [] }, { name: 'B1-2', children: [] }] }, { name: 'B2', children: [] }] }]

ReactDOM.render(
  <Demo categories={categories} />,
  root
)
th, td {
  border: 1px solid black;
}
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>

<div id="root"></div>


推荐阅读