如何避免在 React 中额外包装 <div>?
Posted
技术标签:
【中文标题】如何避免在 React 中额外包装 <div>?【英文标题】:How to avoid extra wrapping <div> in React? 【发布时间】: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,它应该不会很复杂.. 但是限制看起来很烦人。 【参考方案1】:在 React 版本 (16.0)]1 中删除了此要求,因此现在您可以避免使用该包装器。
你可以使用React.Fragment来渲染一个元素列表而无需创建父节点,官方示例:
render()
return (
<React.Fragment>
<ChildA />
<ChildB />
<ChildC />
</React.Fragment>
);
更多:Fragments
【讨论】:
好消息 DmitryUlyanets。有计划的发布日期吗? 自2017年9月26日起发布,见reactjs.org/blog/2017/09/26/react-v16.0.html 也可以使用简写: > 代替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 中添加一个特殊的片段语法, 不需要钥匙。
【讨论】:
> 的新速记语法很棒。但是,我仍然对此有很多复杂的感觉。 @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
这当然不是你在实践中会做的事情,但它是一个很好的学习机会。
【讨论】:
以上是关于如何避免在 React 中额外包装 <div>?的主要内容,如果未能解决你的问题,请参考以下文章