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([]);
});