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

IT技术 reactjs
2021-04-02 09:34:14

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

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>或类似的东西中?

6个回答

这是目前的一个限制,但可能会在未来的某个时候得到修复(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 中,您将能够从渲染返回一个数组。

另一个更新

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

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

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

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

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

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

function RowPair() {
  return <React.Fragment>
    <tr><td>First</td></tr>
    <tr><td>Second</td></tr>
  </React.Fragment>
}
为什么大家都说这个好用???未捕获的错误:x.render():必须返回有效的 React 元素(或 null)。您可能返回了 undefined、数组或其他一些无效对象。
2021-05-25 09:34:14
我不明白所有的赞成票 - 这根本不能回答问题。问题是如何在没有父元素的情况下呈现兄弟元素,而这个答案仍然呈现父元素。
2021-05-29 09:34:14
@FakeRainBrigand 我看到了这个问题。它不是“无状态组件”,它是一个返回数组的函数。无状态组件不能返回数组,也不能将简单的函数连接到 Redux 存储。
2021-06-11 09:34:14
@PetrPeller 你在使用 jsx 吗?在这个例子中,我像一个函数一样调用它。
2021-06-13 09:34:14
@Xogle React API 中的某些内容一定发生了变化。似乎不再起作用了。
2021-06-14 09:34:14

我知道这是一个旧帖子,但也许我的回答可能对像我这样的新手有所帮助。

在 React 16.2 中,添加了Fragment 的改进支持

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

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

你可以用<></>包裹它<Fragment></Fragment>

如果您想传递一些属性,在撰写本文时支持,并且您必须使用,<Fragment />因为短语法<></>不接受属性。

注意:如果您打算使用简短的语法,请确保您使用的是Babel 7

来源参考

正是我所追求的,谢谢!另外,以防万一其他人需要它: import React, { Fragment } from 'react'
2021-06-02 09:34:14
我无法让它工作,即使我安装了 Babel-cli ......即使仅用于 <> 解决方案。怎么可能@onoya 我很快就会发帖,
2021-06-12 09:34:14
我似乎无法Fragment在他们的存储库中找到 的实现,有人可以告诉我吗?谢谢 :)
2021-06-15 09:34:14

呜呼!React 团队最终添加了这个功能。从 React v16.0 开始,您可以执行以下操作:

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
      <tr key="a"><td>Item 1</td></tr>,
      <tr key="b"><td>Item 2</td></tr>
  ];
}

请在此处查看解释“新渲染返回类型:片段和字符串”完整博客文章

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

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

所以简单地做这样的事情:

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

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

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>
 ];
}

我们可以通过将它们包裹在React.Fragment. 例如

ReactDOM.render(
  <React.Fragment>
     <Item1/>
     <Item2/>
  </React.Fragment>,document.getElementById('root')
);

尽管如此,还有一个更短的手。

ReactDOM.render(
  <>
     <Item1/>
     <Item2/>
  </>,document.getElementById('root')
);

将组件包裹在React.FragmentDOM 中不会向 DOM 添加额外的节点。