key 的作用,新旧子节点对比的过程中,如果新旧子节点的 type & key 相同,就认为是同一个节点,确定新子节点在旧子节点中的位置,方便进行 dom 移动,并且会复用该旧节点,对该旧节点进行更新
利用 node.type 无法确定在旧节点中新节点的位置
const oldNode = [
{
type: 'p',
children: 1,
},
{
type: 'p',
children: 2,
},
]
const newNode = [
{
type: 'p',
children: 3,
},
]
利用 node.type & node.key 来确定在旧节点中新节点的位置
const oldNode = [
{
type: 'p',
children: 1,
key: '1',
},
{
type: 'p',
children: 2,
key: '2',
},
]
const newNode = [
{
type: 'p',
children: 3,
key: '1',
},
]
diff 算法 根据 type & key 确定相同的子节点
const oldNode = {
type: 'div',
children: [
{
type: 'p',
children: 1,
key: '1',
},
{
type: 'p',
children: 2,
key: '2',
},
],
}
const newNode = {
type: 'div',
children: [
{
type: 'p',
children: 3,
key: '1',
},
],
}
function patchChildren(n1, n2, container) {
if (typeof n2.children === 'string') {
} else if (Array.isArray(n2.children)) {
if (Array.isArray(n1.children)) {
const oldChildren = n1.children
const newChildren = n2.children
for (let i = 0; i < newChildren.length; i++) {
const newNode = newChildren[i]
for (let j = 0; j < oldChildren.length; j++) {
const oldNode = oldChildren[j]
if (
newNode.type === oldNode.type &&
newNode.key === oldNode.key
) {
patch(oldNode, newNode, container)
break
}
}
}
}
}
}