52

我有一个包含项目的数组,我想做这样的事情:

<tr>
(until have items in array
<td></td><td></td>)
</tr>

但是如果我这样做,我会收到一个 JSXTransformer 错误:

相邻的 XJS 元素必须包含在封闭标记中

工作版本:

{rows.map(function (rowElement){
    return (<tr key={trKey++}>
        <td className='info' key={td1stKey++}>{rowElement.row[0].value}</td><td key={td2ndKey++}>{rowElement.row[0].count}</td>
        <td className='info' key={td1stKey++}>{rowElement.row[1].value}</td><td key={td2ndKey++}>{rowElement.row[1].count}</td>
        <td className='info' key={td1stKey++}>{rowElement.row[2].value}</td><td key={td2ndKey++}>{rowElement.row[2].count}</td>
        <td className='info' key={td1stKey++}>{rowElement.row[3].value}</td><td key={td2ndKey++}>{rowElement.row[3].count}</td>
        <td className='info' key={td1stKey++}>{rowElement.row[4].value}</td><td key={td2ndKey++}>{rowElement.row[4].count}</td>
                 .......
        </tr>);
})}

我试过这个。但是使用<div>封闭标签它不能正常工作。

在这里回答: 未捕获的错误:不变违规:findComponentRoot(..., ...$110): Unable to find element。这可能意味着 DOM 发生了意外变异

<tbody>
    {rows.map(function (rowElement){
        return (<tr key={trKey++}>
        {rowElement.row.map(function(ball){
            console.log('trKey:'+trKey+' td1stKey'+td1stKey+' ball.value:'+ball.value+' td2ndKey:'+td2ndKey+' ball.count:'+ball.count);
            return(<div key={divKey++}>
                <td className='info' key={td1stKey++}>{ball.value}</td><td key={td2ndKey++}>{ball.count}</td>
            </div>);
        })}
        </tr>);
    })}
</tbody>

请告诉我如何正确包装几个 TD 标签! 我尝试使用指南Dynamic Children,但 JSXTransformer 不允许我这样做。

4

4 回答 4

84

当您返回多个没有包装元素的元素时,通常会发生以下错误

相邻的 XJS 元素必须包含在封闭标记中

return (
    <li></li>
    <li></li>
);

这不起作用,因为您实际上返回了两个结果,您只需要返回一个 DOM 节点(有或没有子节点),如

return (
    <ul>
        <li></li>
        <li></li>
    </ul>
);

// or 

return (<ul>
    {items.map(function (item) {
        return [<li></li>, <li></li>];
    })}
</ul>);

为了让我正确回答你的问题,你能提供一个 JSFiddle 吗?我试图猜测您要做什么,并且继承了它的JSFiddle工作。

当使用 div 作为包装器时,它实际上从未渲染到 DOM(不知道为什么)。

<tr data-reactid=".0.0.$1">
    <td class="info" data-reactid=".0.0.$1.$0.0">1</td>
    <td data-reactid=".0.0.$1.$0.1">2</td>
    <td class="info" data-reactid=".0.0.$1.$1.0">1</td>
    <td data-reactid=".0.0.$1.$1.1">2</td>
    <td class="info" data-reactid=".0.0.$1.$2.0">1</td>
    <td data-reactid=".0.0.$1.$2.1">2</td>
    <td class="info" data-reactid=".0.0.$1.$3.0">1</td>
    <td data-reactid=".0.0.$1.$3.1">2</td>
</tr>

编辑:反应 16+

从 React 16 开始,您现在可以使用片段。

你现在会这样做

return <>
    <li></li>
    <li></li>
<>;

或者您可以使用<React.Fragment>,<>是 HTML 片段的简写,它基本上只是一个充当容器的临时父元素,一旦附加到文档中,它就不再存在了。

https://reactjs.org/docs/fragments.html

https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment

于 2014-07-30T11:06:27.197 回答
48

因此,您有一对<td>要从 a 返回的元素.map。最简单的方法是将它们包装在一个数组中。

<tr>
  {data.map(function(x, i){
    return [
      <td>{x[0]}</td>,
      <td>{x[1]}</td>
    ];
  })}
</tr>

不要忘记第一个之后的逗号</td>

于 2014-07-30T15:56:35.147 回答
1

随着 React 16 的发布,有一个名为 Fragment 的新组件。如果想要返回元素/组件的集合而不必将它们包装在封闭元素中,您可以使用Fragment如下所示:

import { Component, Fragment } from 'react';

class Foo extends Component {

  render() {
    return (
      <Fragment>
        <div>Hello</div
        <div>Stack</div>
        <div>Overflow</div>
      </Fragment>
    );
  }
}
于 2017-12-12T22:47:38.490 回答
0

这是你将如何做到的

<tbody>
    {this.props.rows.map((row, i) =>
      <tr key={i}>
        {row.map((col, j) =>
          <td key={j}>{col}</td>
        )}
      </tr>
    )}
</tbody>
于 2017-07-04T17:12:42.633 回答