From 5bc66a4e69c7de3c2ca53025c234f86275466d4a Mon Sep 17 00:00:00 2001
From: * <8>
Date: Tue, 6 Sep 2022 21:50:47 +0800
Subject: [PATCH 1/4] Match-id-78aab772cb8e654ef883d9b69084d2c4da273119
---
.../src/renderer/diff/nodeDiffComparator.ts | 5 +-
.../ComponentTest/DiffAlgorithm.test.js | 48 +++++++++++++++++++
.../ComponentTest/HookTest/UseEffect.test.js | 2 +-
3 files changed, 52 insertions(+), 3 deletions(-)
create mode 100644 scripts/__tests__/ComponentTest/DiffAlgorithm.test.js
diff --git a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
index 8e029fb6..9334116f 100644
--- a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
+++ b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
@@ -294,8 +294,9 @@ function diffArrayNodesHandler(
if (rightOldIndex < 0 || rightOldNode === null) {
break;
}
-
- canBeReuse = checkCanReuseNode(rightOldNode, newChildren[rightIdx - 1]);
+ // 新旧节点的index应该相同才能复用,null会影响位置
+ const samePosition = rightOldNode.eIndex === rightIdx - 1;
+ canBeReuse = checkCanReuseNode(rightOldNode, newChildren[rightIdx - 1]) && samePosition;
// 不能复用,break
if (!canBeReuse) {
break;
diff --git a/scripts/__tests__/ComponentTest/DiffAlgorithm.test.js b/scripts/__tests__/ComponentTest/DiffAlgorithm.test.js
new file mode 100644
index 00000000..0f5ab14d
--- /dev/null
+++ b/scripts/__tests__/ComponentTest/DiffAlgorithm.test.js
@@ -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 ? : null}
+ {current === 2 ? : null}
+ {current === 3 ? : null}
+ >
+ );
+ }
+
+ Horizon.render(, container);
+ expect(fn).toHaveBeenCalledTimes(1);
+
+ update(2);
+ expect(fn).toHaveBeenCalledTimes(2);
+
+ update(3);
+ expect(fn).toHaveBeenCalledTimes(3);
+
+ update(1);
+ expect(fn).toHaveBeenCalledTimes(4);
+ });
+});
diff --git a/scripts/__tests__/ComponentTest/HookTest/UseEffect.test.js b/scripts/__tests__/ComponentTest/HookTest/UseEffect.test.js
index a88cb813..443894a5 100644
--- a/scripts/__tests__/ComponentTest/HookTest/UseEffect.test.js
+++ b/scripts/__tests__/ComponentTest/HookTest/UseEffect.test.js
@@ -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([]);
});
From ec83aff5e62f1887f415093f3816bf458229ce79 Mon Sep 17 00:00:00 2001
From: * <8>
Date: Wed, 7 Sep 2022 11:27:22 +0800
Subject: [PATCH 2/4] Match-id-91b148af957f0c2f4043f45a93a8a6e8929a0507
---
.../src/renderer/diff/nodeDiffComparator.ts | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
index 9334116f..183e6dd9 100644
--- a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
+++ b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
@@ -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,12 @@ function checkCanReuseNode(oldNode: VNode | null, newChild: any): boolean {
return oldKey === null;
}
if (newChild.vtype === TYPE_COMMON_ELEMENT || newChild.vtype === TYPE_PORTAL) {
- return oldKey === newChild.key;
+ if(oldKey || newChild.key) {
+ return oldKey === newChild.key;
+ } else {
+ // 新旧节点的index应该相同才能复用,null会影响位置
+ return oldNode?.eIndex === newNodeIdx;
+ }
}
}
@@ -254,7 +259,7 @@ function diffArrayNodesHandler(
nextOldNode = oldNode.next;
}
- canBeReuse = checkCanReuseNode(oldNode, newChildren[leftIdx]);
+ canBeReuse = checkCanReuseNode(oldNode, newChildren[leftIdx], leftIdx);
// 不能复用,break
if (!canBeReuse) {
oldNode = oldNode ?? nextOldNode;
@@ -294,9 +299,8 @@ function diffArrayNodesHandler(
if (rightOldIndex < 0 || rightOldNode === null) {
break;
}
- // 新旧节点的index应该相同才能复用,null会影响位置
- const samePosition = rightOldNode.eIndex === rightIdx - 1;
- canBeReuse = checkCanReuseNode(rightOldNode, newChildren[rightIdx - 1]) && samePosition;
+
+ canBeReuse = checkCanReuseNode(rightOldNode, newChildren[rightIdx - 1], rightIdx - 1);
// 不能复用,break
if (!canBeReuse) {
break;
From b55f7c4f22c07490693682b50d9e5a70140a6e6d Mon Sep 17 00:00:00 2001
From: * <8>
Date: Wed, 7 Sep 2022 17:42:28 +0800
Subject: [PATCH 3/4] Match-id-e4196e9fd763be3e06cc2c404f9780e4664daff7
---
libs/horizon/src/renderer/diff/nodeDiffComparator.ts | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
index 183e6dd9..84462e0e 100644
--- a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
+++ b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
@@ -70,7 +70,8 @@ function checkCanReuseNode(oldNode: VNode | null, newChild: any, newNodeIdx: num
return oldKey === null;
}
if (newChild.vtype === TYPE_COMMON_ELEMENT || newChild.vtype === TYPE_PORTAL) {
- if(oldKey || newChild.key) {
+ // key存在时用key判断复用
+ if (oldKey != null || newChild.key != null) {
return oldKey === newChild.key;
} else {
// 新旧节点的index应该相同才能复用,null会影响位置
From 4b62e8ee48b902f628827b895a5a8cf9f90a4a25 Mon Sep 17 00:00:00 2001
From: * <8>
Date: Wed, 7 Sep 2022 17:52:26 +0800
Subject: [PATCH 4/4] Match-id-999bd213135d2e503b18dc8b65ad7e4c7f627294
---
libs/horizon/src/renderer/diff/nodeDiffComparator.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
index 84462e0e..686b0692 100644
--- a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
+++ b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts
@@ -71,7 +71,7 @@ function checkCanReuseNode(oldNode: VNode | null, newChild: any, newNodeIdx: num
}
if (newChild.vtype === TYPE_COMMON_ELEMENT || newChild.vtype === TYPE_PORTAL) {
// key存在时用key判断复用
- if (oldKey != null || newChild.key != null) {
+ if (oldKey !== null || newChild.key !== null) {
return oldKey === newChild.key;
} else {
// 新旧节点的index应该相同才能复用,null会影响位置