Repository navigation
Fragment
Anshi edited this page Apr 19, 2019
·
1 revision
fragment 是写 key 的前置条件吧,因为我发现 react 源码在针对数组的子元素时,会将其标记为一个 Fragment 类型的 fiber。

如上图,针对 data 渲染出的数组元素,react 会使用一个 fragment fiber 包裹,渲染其子元素,也就是这个数组。
function updateFragmentComponent(wipFiber: Fiber): void {
const newChildElements = wipFiber.pendingProps.children;
reconcileChildrenArray(wipFiber, newChildElements);
}fragmentComponent 的结构类似 hostComponent,在处理这样的 fiber 的 work 时没有额外的操作。
值得注意的是, fiber 节点里的 tag 和 type 两个属性,tag 属性是 fiber 自有的,在处理 work 时的标识符,常见的值如下:

type 属性是继承自 element ,类型有function|class|string|symbol (这里类型分的不严谨),对于 Fragment 其 type 是一个 symbol 值。
export const REACT_FRAGMENT_TYPE = Symbol.for('react.fragment')所以在渲染 fragment 元素时,需要一个 type => tag 的映射。
Reconcile - 渲染 fragment 子元素
case 'symbol':
if (ele.type === REACT_FRAGMENT_TYPE) {
tag = Fragment;
}
/* ele.type 的typeof 怎么是 symbol + function */
break;除了主动在 jsx 中引入 fragment 元素外,react 还会在处理数组元素时,默认用一个 fragment 包裹,一如文章开头所述,我想这就是react 在16 后支持 return 一个数组的原因吧。
if (Array.isArray(ele)) {
ele = {
type: REACT_FRAGMENT_TYPE,
props: { children: [...ele] },
key: ele.key
};
} "plugins": [
["@babel/plugin-transform-react-jsx", { "pragma":"createElement","pragmaFrag":"Fragment" }]
]由于在调试时想使用 jsx 语法编写,所以引用了plugin-transform-react-jsx,配置如下(其实不配置也可以,因为我们的命名和导出规则都参照的 react)。