如何避免在React中额外包装<div>?


113

今天,我开始学习ReactJS,一个小时后面对了这个问题。我想在页面上的div内插入一个具有两行的组件。下面是我正在做的简化示例。

我有一个html:

<html>
..
  <div id="component-placeholder"></div>
..
</html>

渲染功能如下:

...
render: function() {

    return(
        <div className="DeadSimpleComponent">
            <div className="DeadSimpleComponent__time">10:23:12</div >
            <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
        </div>
    )
}
....

下面我称渲染:

ReactDOM.render(<DeadSimpleComponent/>, document.getElementById('component-placeholder'));

生成的HTML如下所示:

<html>
..
  <div id="component-placeholder">
    <div class="DeadSimpleComponent">
            <div class="DeadSimpleComponent__time">10:23:12</div>
            <div class="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
    </div>
</div>
..
</html>

我不是很高兴React强迫我将它们全部包装在div“ DeadSimpleComponent”中。没有显式的DOM操作,什么是最好,最简单的解决方法?

更新7/28/2017:React的维护者在React 16 Beta 1中增加了这种可能性

React 16.2开始,您可以执行以下操作:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

4
完美的命名习惯;-)
Kirill Reznikov

我可以看一下您的HTML文件吗?我看错了你的问题。我可能有解决方法。
Louis93 2015年


您对具有单个元素的组件有疑问吗?真?
多米尼克

你什么意思?我只是在尝试React,它应该不会很复杂。。但是限制看起来很烦人。
Kirill Reznikov

Answers:


142

此要求已在React版本(16.0)] 1中删除,因此现在您可以避免使用该包装器。

您可以使用React.Fragment来渲染元素列表,而无需创建父节点,例如:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

更多内容:片段


1
好消息DmitryUlyanets。有计划的发行日期吗?
乔纳斯·卡尔巴姆

该版本自2017年9月26日发布,请参见reactjs.org/blog/2017/09/26/react-v16.0.html
Tom

56

2017年12月5日更新:React v16.2.0现在完全支持片段的渲染,并改进了对从组件渲染方法返回多个子对象的支持,而无需在子对象中指定键:

render() {
  return (
    <>
      <ChildA />
      <ChildB />
      <ChildC />
    </>
  );
}

如果您使用的是v16.2.0之前的React版本,也可以<React.Fragment>...</React.Fragment>改用:

render() {
  return (
    <React.Fragment>
      <ChildA />
      <ChildB />
      <ChildC />
    </React.Fragment>
  );
}

原版的:

React v16.0引入了在render方法中返回元素数组而不将其包装在div中的方法:https ://reactjs.org/blog/2017/09/26/react-v16.0.html

render() {
  // No need to wrap list items in an extra element!
  return [
    // Don't forget the keys :)
    <li key="A">First item</li>,
    <li key="B">Second item</li>,
    <li key="C">Third item</li>,
  ];
}

目前,每个元素都需要一个键,以避免键警告,但是在以后的版本中可以更改:

将来,我们可能会在JSX中添加不需要键的特殊片段语法。


<> </>的新速记语法很棒。但是我对此仍然有很多困惑。
Thulani Chivandikwa

@ThulaniChivandikwa您介意表达对速记语法的疑虑吗?
汤姆(Tom)

1
我认为这更多是关于空标记的概念,在JSX中,该标记是奇数的,除非您确切知道它的作用,否则它不是很直观的。
Thulani Chivandikwa

7

您可以使用:

render(){
    return (
        <React.Fragment>
           <div>Some data</div>
           <div>Som other data</div>
        </React.Fragment>
    )
}

有关更多详细信息,请参阅此文档


3

使用[],而不是()来包装整个返回值。

render: function() {
  return[
    <div className="DeadSimpleComponent__time">10:23:12</div >
    <div className="DeadSimpleComponent__date">MONDAY, 2 MARCH 2015</div>
  ]
}


1

仍然需要这样做但BUT React现在确保创建元素而不创建其他DOM元素。

需要额外的包装(通常使用父包装div),因为Reacts createElement方法需要一个type参数either a tag name string (such as 'div' or 'span'), a React component type (a class or a function)。但这是在他们介绍React之前Fragment

请参考此新API文档以获取createElement

React.createElement:创建并返回给定类型的新React元素。type参数可以是标签名称字符串(例如'div'或'span'),React组件类型(类或函数)或React片段类型

这是官方示例,请参考React.Fragment

render() {
  return (
    <React.Fragment>
      Some text.
      <h2>A heading</h2>
    </React.Fragment>
  );
}

0

您将无法摆脱该div因素。React.render()需要返回一个有效的DOM节点。


div被忽略,Knockout.JS做同样的事情。在组件的外部没有样式的div不会产生任何效果。
克里斯·霍克斯

16
@ChrisHawkes,不同意。一个包装div会影响CSS选择器。
Downhillski

当使用语义元素时,您不想完全成为React组件,这成为一个问题。可以说有一个带有header和footer元素的section-tag,在它们之间有一个Google map-container,我们不想在React中使用它。那么将Header作为React组件并将Footer作为React组件,而不必在React组件内部包含额外的div:s将会是一件很不错的事情……如果您完全关心html,那将是愚蠢的设计您输出...
Jonas Carlbaum

0

这是呈现“透明”组件的一种方法:

import React from 'react'

const Show = (props) => {
  if (props.if || false) {
    return (<React.Fragment>{props.children}</React.Fragment>)
  }
  return '';
};

----


<Show if={yomama.so.biq}>
    <img src="https://yomama.so.biq">
    <h3>Yoamama</h3>
<Show>

在此处输入图片说明


0

也有解决方法。下面的代码块无需React.Fragment就可以生成片段。

return [1,2,3].map(i=>{
if(i===1) return <div key={i}>First item</div>
if(i===2) return <div key={i}>Second item</div>
return <div key={i}>Third item</div>
})

0

我知道这个问题已经回答了,您当然可以使用React.Fragment,它不会创建节点,但让我们将div之类的东西分组。

另外,如果您想玩得开心,可以实现(并学到很多东西)一种React模式,该模式消除了多余的div,为此,我真的想分享一个很棒的视频,介绍如何在react代码本身上实现它。

https://www.youtube.com/watch?v=aS41Y_eyNrU

当然,这不是您在实践中会做的事情,但这是一个很好的学习机会。

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.