React多組件並列存在的問題
在使用React的自定義組件時,時常需要將多個自定義組件進行並列顯示。而React在version-15之前,render 函數的返回必須有一個根節點否則將會報錯。而此時常見的解決方法及爲使用div將多個並列的自定義組件進行包裹起來。但這樣一方面會增加頁面渲染的負擔,另一方面有時這種方式不是想要的結果。例如如下的方法:
class ProductTable extends Component {
// ...
render() {
const productGroup = cateArr.map((cate) => {
// ...
return (
<div>
<ProductCategoryRow category={cate}/> // <tr>row</tr>
{
productFiltered.map((product) => {
return <ProductRow
key={product.id}
name={product.name}
price={product.price}/>; // <tr>row</tr>
}
)
}
<div>
)
});
return (
<table>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
</tr>
</thead>
<tbody>
{productGroup}
</tbody>
</table>
)
}
}
export default ProductTable;
在ProductGroup中使用兩個map循環來渲染,一個ProductCategoryRow對應類別下的ProductRow列表。也就是如下的格式:
ProductCategory1:
Product1
Product2
Product3
ProductCategory2:
Product4
Product5
Product6
...
而此時由於ProductCategoryRow和ProductRow自定義組件中渲染的都是<tbody>元素中的錶行<tr>。但由於return中的兩個組件無法直接並列,所以需要使用<div>進行了包裹。但此時在表格中這樣的嵌套方式是不合適的,而且React也會給出相關的Warning信息:
Warning: validateDOMNesting(...): <div> cannot appear as a child of <tbody>.
...
使用React.Fragment避免div的嵌套
對於以上問題,React 16版本中提供了兩種方式來進行解決,一種是使用如下的格式來實現多個組件的直接並列排列:
import React from 'react';
export default function () {
return [
<Component1 >
<Component2 >
<Component3 >
];
}
第二中方式即使用React.Fragment標籤做爲不可見的包裹元素。使用該方式上述問題代碼的解決方案就可以直接使用React.Fragment標籤替換之前的div來進行包裹:
return (
<React.Fragment>
<ProductCategoryRow category={cate}/>
{
productFiltered.map((product) => {
return <ProductRow
key={product.id}
name={product.name}
price={product.price}/>;
}
)
}
</React.Fragment>
)
對於React.Fragment具有一種簡寫的方式,即使用如下的格式:
return (
<>
<ProductCategoryRow category={cate}/>
{
productFiltered.map((product) => {
return <ProductRow
key={product.id}
name={product.name}
price={product.price}/>;
}
)
}
</>
)
通過以上方式便可以很好的解決上述React多組件直接並列的問題。