Match-id-90040cb5364b3b0734f58a809940ab8d0ef30246

This commit is contained in:
* 2022-09-07 17:55:34 +08:00 committed by *
commit 628528cb86
3 changed files with 59 additions and 5 deletions

View File

@ -55,7 +55,7 @@ function deleteVNodes(parentVNode: VNode, startDelVNode: VNode | null, endVNode?
}
}
function checkCanReuseNode(oldNode: VNode | null, newChild: any): boolean {
function checkCanReuseNode(oldNode: VNode | null, newChild: any, newNodeIdx: number): boolean {
if (newChild === null) {
return false;
}
@ -70,7 +70,13 @@ function checkCanReuseNode(oldNode: VNode | null, newChild: any): boolean {
return oldKey === null;
}
if (newChild.vtype === TYPE_COMMON_ELEMENT || newChild.vtype === TYPE_PORTAL) {
// key存在时用key判断复用
if (oldKey !== null || newChild.key !== null) {
return oldKey === newChild.key;
} else {
// 新旧节点的index应该相同才能复用null会影响位置
return oldNode?.eIndex === newNodeIdx;
}
}
}
@ -254,7 +260,7 @@ function diffArrayNodesHandler(
nextOldNode = oldNode.next;
}
canBeReuse = checkCanReuseNode(oldNode, newChildren[leftIdx]);
canBeReuse = checkCanReuseNode(oldNode, newChildren[leftIdx], leftIdx);
// 不能复用break
if (!canBeReuse) {
oldNode = oldNode ?? nextOldNode;
@ -295,7 +301,7 @@ function diffArrayNodesHandler(
break;
}
canBeReuse = checkCanReuseNode(rightOldNode, newChildren[rightIdx - 1]);
canBeReuse = checkCanReuseNode(rightOldNode, newChildren[rightIdx - 1], rightIdx - 1);
// 不能复用break
if (!canBeReuse) {
break;

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
*/
import * as Horizon from '@cloudsop/horizon/index.ts';
describe('Diff Algorithm', () => {
it('null should diff correctly', () => {
const fn = jest.fn();
class C extends Horizon.Component {
constructor() {
super();
fn();
}
render() {
return 1;
}
}
let update;
function App() {
const [current, setCurrent] = Horizon.useState(1);
update = setCurrent;
return (
<>
{current === 1 ? <C /> : null}
{current === 2 ? <C /> : null}
{current === 3 ? <C /> : null}
</>
);
}
Horizon.render(<App text="app" />, container);
expect(fn).toHaveBeenCalledTimes(1);
update(2);
expect(fn).toHaveBeenCalledTimes(2);
update(3);
expect(fn).toHaveBeenCalledTimes(3);
update(1);
expect(fn).toHaveBeenCalledTimes(4);
});
});

View File

@ -81,7 +81,7 @@ describe('useEffect Hook Test', () => {
expect(LogUtils.getAndClear()).toEqual([]);
// 在执行新的render前会执行完上一次render的useEffect所以LogUtils会加入'NewApp effect'。
Horizon.render([na], container);
expect(LogUtils.getAndClear()).toEqual(['NewApp effect']);
expect(LogUtils.getAndClear()).toEqual(['NewApp effect', 'NewApp']);
expect(container.textContent).toBe('NewApp');
expect(LogUtils.getAndClear()).toEqual([]);
});