如何呈现同级元素而不将其包装在父标签中?


82

在大多数情况下,拥有父标签不是问题。

React.createClass({
    render: function() {
        return (
            <tbody>
                <tr><td>Item 1</td></tr>
                <tr><td>Item 2</td></tr>
            </tbody>
        );
    }
});

但是在某些情况下,在一个渲染函数中没有兄弟元素而没有父元素是有意义的,尤其是在使用表的情况下,您不想将表行包装在中div

React.createClass({
    render: function() {
        return (
            <tr><td>Item 1</td></tr>
            <tr><td>Item 2</td></tr>
        );
    }
});

第二个示例给出以下错误:Adjacent XJS elements must be wrapped in an enclosing tag while parsing file

如何呈现两个兄弟元素而不将它们包装在a<div>或类似的东西中?


3
我似乎总是很难找到这个问题/答案,所以我决定自己问/答案。欢迎提供其他解释/答案。
thealexbaron'2

另一个示例是导航项
Tjorriemorrie '16

Answers:


66

目前这是一个限制,但将来可能会解决(在github repo上有一些未解决的问题)。

现在,您可以使用一个返回数组的函数(这基本上是一个无状态组件):

function things(arg, onWhatever){
    return [
        <tr><td>Item 1</td></tr>,
        <tr><td>Item 2</td></tr>
    ];
}

并在您的组件中使用它。

return (
    <table><tbody>
      {things(arg1, this.handleWhatever)}
      {things(arg2, this.handleWhatever)}
    </tbody></table>
);

更新资料

在React 16中,您将能够从render返回一个数组。

另一个更新

现在,您可以返回顶级数组,也可以使用<React.Fragment>

对于数组,我们需要在每个项目上放置一个键,因为React不知道这两个元素是常量,而不是动态创建的列表:

function RowPair() {
  return [
    <tr key="first"><td>First</td></tr>,
    <tr key="second"><td>Second</td></tr>,
  ]
}

使用React.Fragment,它的行为更像是将其包装在<div>或类似容器中,key如果我们不是动态构建子代,则不需要。首先,我们可以将数组包装在Fragment中:

function RowPair() {
  return <React.Fragment>{[
    <tr key="first"><td>First</td></tr>,
    <tr key="second"><td>Second</td></tr>,
  ]}</React.Fragment>
}

然后我们可以key完全消除数组和:

function RowPair() {
  return <React.Fragment>
    <tr><td>First</td></tr>
    <tr><td>Second</td></tr>
  </React.Fragment>
}

2
为什么每个人都说这可行????未捕获的错误:x.render():必须返回有效的React元素(或null)。您可能返回了undefined,数组或其他无效对象。
Xogle 2016年

@Xogle在React API中必须进行了某些更改。似乎不再起作用了。
Petr Peller

1
@FakeRainBrigand我看到了问题。它不是一个“无状态组件”,而是一个返回数组的函数。无状态组件无法返回数组,并且您无法将简单函数连接到Redux存储。
彼得·佩勒

@PetrPeller您在使用jsx吗?在示例中,我像函数一样调用它。
Brigand

我不了解所有的支持-这根本无法回答问题。问题是如何在没有父元素的情况下呈现兄弟元素,而此答案仍在呈现父元素。
Dancrumb

33

我知道这是一篇过时的文章,但也许​​我的回答可能会对像我这样的新手有所帮助。

在React 16.2中,增加了对Fragments的支持。

您现在可以像这样返回它:

return (
  <>
    <tr><td>Item 1</td></tr>
    <tr><td>Item 2</td></tr>
  </>
);

您可以使用<></>或包装它<Fragment></Fragment>

如果要传递某些属性,在编写本文时仅支持,并且<Fragment />由于短语法<></>不接受属性,因此必须使用键。

注意:如果要使用简短语法,请确保使用Babel 7

来源参考


1
正是我所追求的,谢谢!此外,万一别人需要它:进口反应,{}片段从“反应”
克里斯-

我似乎Fragment在其存储库中找不到的实现,请有人告诉我吗?谢谢:)
拉蒙·巴尔塔撒

即使我安装了Babel-cli,我也无法使它工作,即使仅用于<>解决方案。@onoya怎么可能,我很快就会发布主题,
Gaelle


3

在大多数情况下,拥有一个父元素是有帮助的,例如,您可以拥有一个父className,它可以针对子元素样式和其他一些情况。

但是,如果您真的不想这样做,可以使用 React.Fragment

因此,只需执行以下操作:

<React.Fragment>
  <First />
  <Second />
  <Third />
</React.Fragment>

16.2版开始,还有一个缩短版本,也使用<>,在render函数中看起来像这样:

render() {
  return (
    <>
      <First />
      <Second />
      <Third />
    </>
  );
}

此外,如果使用16.0及更高版本,则可以返回不需要父包装的元素数组,如下所示:

render() {
 return [
  <h1 key="heading">Hello from Alireza!</h1>,
  <p key="first">Here where I'm!</p>,
  <p key="second">And again here :)</p>
 ];
}

0

您可以将其包装在方括号中,如下所示:

React.createClass({
    render: function() {
        return (
          [
            <tr><td>Item 1</td></tr>
            <tr><td>Item 2</td></tr>
          ]
        );
    }
});

如果还需要Object.keys()在退货中使用该怎么办?
Juha Untinen

例如。 return ( [ <tr><td>Header</td></tr>{ Object.keys(this.props.data).map(function(item) { <tr><td>{data}</td></tr> }) } ] ); 15.4.2,它Unexpected token, expected ,在回程内给出了开括号
Juha Untinen 17-4-26

尝试这样的事情:return({Object.keys(this.props.data).map(function(item){<tr> <td> {data} </ td> </ tr>})。unshift({< tr> <td> Header </ td> </ tr>})}));
Vitaliy Andrusishyn

这不起作用,仍然需要用逗号分隔<tr> -s
Philipp Munin

0

这个例子对我来说很好:

let values = [];

if (props.Values){
  values = [
    <tr key={1}>
      <td>props.Values[0].SomeValue</td>
    </tr>
  ,
    <tr key={2}>
        <td>props.Values[1].SomeValue</td>
        </tr>
    ];
}

return (
    <table className="no-border-table table">
      <tbody>
        <tr>
            <th>Some text</th>
        </tr>
        {values}
      </tbody>
    </table>
)

0

像这样的语法对我有用

this.props.map((data,index)=>{return( [ <tr>....</tr>,<tr>....</tr>];)});

-2

对于使用TypeScript的用户,正确的语法是:

return [
  (
    <div>Foo</div>
  ),
  (
    <div>Bar</div>
  )
];

1
这与@thealexbaron的答案相同,并且与TypeScript没有关系
andrewarchi
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.