在React 16.2中,增加了对Fragments的支持。更多信息可以在React的博客文章中找到。
下面的代码大家都很熟悉:
render() {
return (
// Extraneous div element :(
<div>
Some text.
<h2>A heading</h2>
More text.
<h2>Another heading</h2>
Even more text.
</div>
);
}
是的,我们需要一个容器div,但这不是一个大的交易。
在React 16.2中,我们可以这样做来避免周围的容器div:
render() {
return (
<Fragment>
Some text.
<h2>A heading</h2>
More text.
<h2>Another heading</h2>
Even more text.
</Fragment>
);
}
无论哪种情况,我们仍然需要一个容器元素来包围内部元素。
我的问题是,为什么使用Fragment更可取?它对性能有帮助吗?如果有,为什么?想要一些见解。
增加了以前JSX不可能的特性
更好的语义jsx标记。包装器元素是在需要的时候使用的,而不是因为它们是被迫使用的。
更少的整体dom标记(增加的渲染性能和更少的内存开销)
它很简单,当您不需要包装器元素时,您不必强制使用它。拥有更少的元素很好,但我认为最大的好处是能够在jsx中呈现以前不可能呈现的元素,并为包装器元素添加更好的语义,因为它们现在是可选的。
这在以前是不可能的:
<select>
{this.renderOptions()}
</select>
在React 15中,你无法判断是否需要wrapper元素:
<span>
<h1>Hello</h1>
{this.getContent()}
</span>
在使用React时,有时需要呈现多个元素或返回一组相关项。这里有一个例子:
function App() {
return (
<h1>Hello React!</h1>
<h1>Hello React Again!</h1>
);
}
如果你试图用上面的代码运行你的应用程序,你会遇到一个错误,说明相邻的JSX元素必须包装在一个封闭的标记中。这意味着您需要在父div中包装这两个元素。
function App() {
return (
<div>
<h1>Hello React!</h1>
<h1>Hello React Again!</h1>
</div>
);
}
这样做可以修复错误,但会带来一定程度的风险。您正在向DOM添加一个额外的节点,这是不必要的。在这种情况下,上面的子组件将被包含在父组件中,这就成了一个问题。
function Table() {
return (
<table>
<td>This is a Table Component</td>
<Columns />
</table>
);
}
function Columns() {
return (
<div>
<td>Hello React!</td>
<td>Hello React Again!</td>
</div>
);
}
Table组件的结果HTML将无效,因为添加了额外的div。
function Table() {
return (
<table>
<td>This is a Table Component</td>
<div>
<td>Hello React!</td>
<td>Hello React Again!</td>
</div>
</table>
);
}
让我们来看看使用React Fragment来解决这个问题的更好方法,它不会向DOM添加任何额外的节点。语法如下所示:
function Columns() {
return (
<React.Fragment>
<td>Hello React!</td>
<td>Hello React Again!</td>
</React.Fragment>
);
}
你也可以使用短语法<></>来声明Fragment。
function Columns() {
return (
<>
<td>Hello React!</td>
<td>Hello React Again!</td>
</>
);
}