1. 简介
React中的一个常见模式是一个组件返回多个元素。Fragments允许你将子列表分组,而无需向DOM添加额外节点。
2. 使用场景
当我们想封装一个table组件,并将table组件中纵向的Columns单独抽取出来进行封装,因为一行中可能有很多列,所以Columns中有很多td
,而React中不允许有多个根组件,所以代码如下:
- Table/index.js
import { Component } from 'react';
import Columns from '../Columns';
export default class Table extends Component {
render() {
return (
<table>
<thead>
<tr>
<Columns />
</tr>
</thead>
</table>
)
}
}
- Columns/index.js
import { Component } from 'react';
export default class Columns extends Component {
render() {
return (
<div>
<td>第一列</td>
<td>第二列</td>
</div>
)
}
}
此时在使用时,页面会报警告:
validateDOMNesting(...): <td> cannot appear as a child of <div>.
validateDOMNesting(...): <div> cannot appear as a child of <tr>.
在浏览器中查看DOM元素我们会发现:
从元素和警告的字面意思我们也可以理解,即td不能作为div的子元素,div不能作为tr的子元素,那么此时React.Fragments的作用就出现啦,Table组件不变,我们将上述Columns组件进行修改
- Columns/index.js
import { Component } from 'react';
import { Fragment } from 'react';
export default class Columns extends Component {
render() {
return (
<Fragment>
<td>第一列</td>
<td>第二列</td>
</Fragment>
)
}
}
此时会发现警告内容消失了,渲染之后的DOM元素也是正常的
从我的理解上看,Fragment似乎有些类似于Vue中我们常用的template,在渲染元素的时候不会渲染该标签,不会改变原本的格式
3. 简写
我们也可以使用更简短的语法来声明Fragments,<></>
,但它并不支持key或属性
export default class Columns extends Component {
render() {
return (
<>
<td>第一列</td>
<td>第二列</td>
</>
)
}
}
4. 带key的Fragments
若是循环某个具体的组件,也是需要key做唯一的标识,key是唯一可以传递给Fragment的属性。
<dl>
{props.items.map(item => (
// 没有`key`,React 会发出一个关键警告
<React.Fragment key={item.id}>
<dt>{item.term}</dt>
<dd>{item.description}</dd>
</React.Fragment>
))}
</dl>
如果有用,点个赞呗~
总结用法,希望可以帮助到你,
我是Ably,你无须超越谁,只要超越昨天的自己就好~