【问题标题】:How to avoid extra wrapping <div> in React?如何避免在 React 中额外包装 <div>?
【发布时间】:2016-02-19 08:44:01
【问题描述】:

今天我开始学习 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 操作的情况下,最好和最简单的解决方法是什么?

2017 年 7 月 28 日更新:React 的维护者在 React 16 Beta 1 中添加了这种可能性

由于React 16.2,你可以这样做:

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

【问题讨论】:

  • 完美的命名习惯 ;-)
  • 我可以看看你的 HTML 文件吗?我误读了你的问题。不过我可能有一个解决方法。
  • 这样的:jsfiddle.net/qawumm3v
  • 您对具有单个元素的组件有疑问?真的吗?
  • 什么意思?我只是在尝试 React,它应该不会很复杂.. 但是限制看起来很烦人。

标签: javascript reactjs


【解决方案1】:

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

你可以使用React.Fragment来渲染一个元素列表而无需创建父节点,官方示例:

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

更多:Fragments

【讨论】:

【解决方案2】:

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

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

如果您使用的是 v16.2.0 之前的 React 版本,也可以使用 &lt;React.Fragment&gt;...&lt;/React.Fragment&gt; 代替:

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 中添加一个特殊的片段语法, 不需要钥匙。

【讨论】:

  • > 的新速记语法很棒。但是,我仍然对此有很多复杂的感觉。
  • @ThulaniChivandikwa 您介意说出您对速记语法的疑虑吗?
  • 我认为这更多是关于空标签的概念在 JSX 中很奇怪并且不是很直观,除非您确切知道它的作用。
【解决方案3】:

你可以使用:

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

更多详情请参考this documentation

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      我创建了一个组件来包装没有 DIV 的子组件。它被称为影子包装器:https://www.npmjs.com/package/react-shadow-wrapper

      【讨论】:

      • 我在你的包裹上发布了一个问题,你能看看吗?谢谢
      【解决方案6】:

      这仍然是必需的但是 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 之前。

      参考this NEW api doc for createElement

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

      这里是官方例子,参考React.Fragment

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

      【讨论】:

        【解决方案7】:

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

        【讨论】:

        • div 被忽略,Knockout.JS 做同样的事情。在组件的外部有一个没有样式的 div 不会产生任何影响。
        • @ChrisHawkes,不同意。一个包装器 div 会影响 css 选择器。
        • 在使用语义元素时,您不想完全成为 React 组件,这会成为一个问题。假设有一个带有页眉和页脚元素的 section-tag,在它们之间有一个 google map-container,我们不想在 React 中使用它。然后将 header 作为 React 组件,将 Footer 作为 React 组件会很好,而不必在 React 组件内部包含额外的 div:s ......如果你完全关心 html,那是愚蠢的设计你输出...
        【解决方案8】:

        这是渲染“半透明”组件的一种方法:

        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>
        

        【讨论】:

          【解决方案9】:

          也有解决方法。下面的代码块生成片段而不需要 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>
          })
          

          【讨论】:

            【解决方案10】:

            我知道这个问题已经得到解答,你当然可以使用 React.Fragment,它不会创建节点,但可以让你对 div 之类的东西进行分组。

            另外,如果你想玩得开心,你可以实现(并学习很多东西)一个 React 模式,它可以删除多余的 div,为此我真的想分享一个很棒的视频,介绍如何在 react 代码库上做到这一点自己。

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

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

            【讨论】:

              猜你喜欢
              • 2017-12-07
              • 1970-01-01
              • 1970-01-01
              • 2019-02-11
              • 2012-01-26
              • 2023-03-22
              • 2017-08-01
              • 2018-12-09
              • 1970-01-01
              相关资源
              最近更新 更多