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多组件直接并列的问题。