diff --git a/.changeset/clear-numbers-call.md b/.changeset/clear-numbers-call.md
new file mode 100644
index 0000000000..bff19ec1a0
--- /dev/null
+++ b/.changeset/clear-numbers-call.md
@@ -0,0 +1,23 @@
+---
+"@lynx-js/react": patch
+---
+
+During hydration, replace update with insert + remove for same-type `` with different `item-key` so the Lynx Engine detects changes.
+
+```html
+Hydrate List B into List A:
+
+List A:
+
+ hello
+ world
+
+
+List B:
+
+ hello
+ world
+
+```
+
+Previously this case was hydrated as an update; it is now emitted as insert + remove to ensure SDK detection.
diff --git a/packages/react/runtime/__test__/list.test.jsx b/packages/react/runtime/__test__/list.test.jsx
index 4162a77e5a..c9136f9828 100644
--- a/packages/react/runtime/__test__/list.test.jsx
+++ b/packages/react/runtime/__test__/list.test.jsx
@@ -1313,6 +1313,127 @@ describe('list reload', () => {
,
);
+ it('For same-type list-item with different item-key, do an insert + remove so the SDK detects it.', () => {
+ const b = new SnapshotInstance(s1);
+ b.ensureElements();
+ const root = b.__element_root;
+
+ const s3 = __SNAPSHOT__(
+
+ World
+ ,
+ );
+
+ const d1 = new SnapshotInstance(s3); // a
+ const d2 = new SnapshotInstance(s3); // b
+ const d3 = new SnapshotInstance(s3); // c
+ const d4 = new SnapshotInstance(s3); // d
+
+ d1.setAttribute(0, { 'item-key': 'a' });
+ d2.setAttribute(0, { 'item-key': 'b' });
+ d3.setAttribute(0, { 'item-key': 'c' });
+ d4.setAttribute(0, { 'item-key': 'd' });
+ b.insertBefore(d1);
+ b.insertBefore(d2);
+ b.insertBefore(d3);
+ b.insertBefore(d4);
+
+ __pendingListUpdates.flush();
+
+ const bb = new SnapshotInstance(s1);
+ {
+ const d1 = new SnapshotInstance(s3); // a1
+ const d2 = new SnapshotInstance(s3); // b1
+ const d3 = new SnapshotInstance(s3); // c1
+ const d4 = new SnapshotInstance(s3); // d1
+ d1.setAttribute(0, { 'item-key': 'a1' });
+ d2.setAttribute(0, { 'item-key': 'b1' });
+ d3.setAttribute(0, { 'item-key': 'c1' });
+ d4.setAttribute(0, { 'item-key': 'd1' });
+ bb.insertBefore(d1);
+ bb.insertBefore(d2);
+ bb.insertBefore(d3);
+ bb.insertBefore(d4);
+ }
+
+ hydrate(b, bb);
+ b.unRenderElements();
+
+ expect(root).toMatchInlineSnapshot(`
+
+
+
+
+
+
+ `);
+ });
+
it('list-item with same type - remove', () => {
const b = new SnapshotInstance(s1);
b.ensureElements();
@@ -1359,15 +1480,15 @@ describe('list reload', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_35",
+ "type": "__Card__:__snapshot_a94a8_test_36",
},
{
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_35",
+ "type": "__Card__:__snapshot_a94a8_test_36",
},
{
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_35",
+ "type": "__Card__:__snapshot_a94a8_test_36",
},
],
"removeAction": [],
@@ -1404,15 +1525,15 @@ describe('list reload', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_35",
+ "type": "__Card__:__snapshot_a94a8_test_36",
},
{
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_35",
+ "type": "__Card__:__snapshot_a94a8_test_36",
},
{
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_35",
+ "type": "__Card__:__snapshot_a94a8_test_36",
},
],
"removeAction": [],
@@ -1429,7 +1550,7 @@ describe('list reload', () => {
"insertAction": [
{
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_35",
+ "type": "__Card__:__snapshot_a94a8_test_36",
},
],
"removeAction": [],
@@ -1459,10 +1580,15 @@ describe('list reload', () => {
,
);
- const d1 = new SnapshotInstance(s3);
- const d2 = new SnapshotInstance(s3);
- const d3 = new SnapshotInstance(s4);
- const d4 = new SnapshotInstance(s3);
+ const d1 = new SnapshotInstance(s3); // a
+ const d2 = new SnapshotInstance(s3); // b
+ const d3 = new SnapshotInstance(s4); // c
+ const d4 = new SnapshotInstance(s3); // d
+
+ d1.setAttribute(0, { 'item-key': 'a' });
+ d2.setAttribute(0, { 'item-key': 'b' });
+ d3.setAttribute(0, { 'item-key': 'c' });
+ d4.setAttribute(0, { 'item-key': 'd' });
b.insertBefore(d1);
b.insertBefore(d2);
b.insertBefore(d3);
@@ -1472,10 +1598,14 @@ describe('list reload', () => {
const bb = new SnapshotInstance(s1);
{
- const d1 = new SnapshotInstance(s3);
- const d2 = new SnapshotInstance(s4);
- const d3 = new SnapshotInstance(s3);
- const d4 = new SnapshotInstance(s3);
+ const d1 = new SnapshotInstance(s3); // a
+ const d2 = new SnapshotInstance(s4); // c
+ const d3 = new SnapshotInstance(s3); // b
+ const d4 = new SnapshotInstance(s3); // d
+ d1.setAttribute(0, { 'item-key': 'a' });
+ d2.setAttribute(0, { 'item-key': 'c' });
+ d3.setAttribute(0, { 'item-key': 'b' });
+ d4.setAttribute(0, { 'item-key': 'd' });
bb.insertBefore(d1);
bb.insertBefore(d2);
bb.insertBefore(d3);
@@ -1499,20 +1629,24 @@ describe('list reload', () => {
{
"insertAction": [
{
+ "item-key": "a",
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_36",
+ "type": "__Card__:__snapshot_a94a8_test_37",
},
{
+ "item-key": "b",
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_36",
+ "type": "__Card__:__snapshot_a94a8_test_37",
},
{
+ "item-key": "c",
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_37",
+ "type": "__Card__:__snapshot_a94a8_test_38",
},
{
+ "item-key": "d",
"position": 3,
- "type": "__Card__:__snapshot_a94a8_test_36",
+ "type": "__Card__:__snapshot_a94a8_test_37",
},
],
"removeAction": [],
@@ -1521,8 +1655,9 @@ describe('list reload', () => {
{
"insertAction": [
{
+ "item-key": "b",
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_36",
+ "type": "__Card__:__snapshot_a94a8_test_37",
},
],
"removeAction": [
@@ -1588,15 +1723,15 @@ describe('list reload', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_38",
+ "type": "__Card__:__snapshot_a94a8_test_39",
},
{
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_38",
+ "type": "__Card__:__snapshot_a94a8_test_39",
},
{
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_38",
+ "type": "__Card__:__snapshot_a94a8_test_39",
},
],
"removeAction": [],
@@ -1679,19 +1814,19 @@ describe('list reload', () => {
"full-span": true,
"item-key": "1",
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_39",
+ "type": "__Card__:__snapshot_a94a8_test_40",
},
{
"full-span": true,
"item-key": "2",
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_39",
+ "type": "__Card__:__snapshot_a94a8_test_40",
},
{
"full-span": true,
"item-key": "3",
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_39",
+ "type": "__Card__:__snapshot_a94a8_test_40",
},
],
"removeAction": [],
@@ -1707,7 +1842,7 @@ describe('list reload', () => {
"full-span": false,
"item-key": "2",
"to": 1,
- "type": "__Card__:__snapshot_a94a8_test_39",
+ "type": "__Card__:__snapshot_a94a8_test_40",
},
],
},
@@ -1795,19 +1930,19 @@ describe('list reload', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_40",
+ "type": "__Card__:__snapshot_a94a8_test_41",
},
{
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_40",
+ "type": "__Card__:__snapshot_a94a8_test_41",
},
{
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_40",
+ "type": "__Card__:__snapshot_a94a8_test_41",
},
{
"position": 3,
- "type": "__Card__:__snapshot_a94a8_test_40",
+ "type": "__Card__:__snapshot_a94a8_test_41",
},
],
"removeAction": [],
@@ -1817,7 +1952,7 @@ describe('list reload', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_41",
+ "type": "__Card__:__snapshot_a94a8_test_42",
},
],
"removeAction": [
@@ -1876,19 +2011,19 @@ describe('list reload', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_40",
+ "type": "__Card__:__snapshot_a94a8_test_41",
},
{
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_40",
+ "type": "__Card__:__snapshot_a94a8_test_41",
},
{
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_40",
+ "type": "__Card__:__snapshot_a94a8_test_41",
},
{
"position": 3,
- "type": "__Card__:__snapshot_a94a8_test_40",
+ "type": "__Card__:__snapshot_a94a8_test_41",
},
],
"removeAction": [],
@@ -1898,7 +2033,7 @@ describe('list reload', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_41",
+ "type": "__Card__:__snapshot_a94a8_test_42",
},
],
"removeAction": [
@@ -2038,15 +2173,15 @@ describe('list bug', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_46",
+ "type": "__Card__:__snapshot_a94a8_test_47",
},
{
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_46",
+ "type": "__Card__:__snapshot_a94a8_test_47",
},
{
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_46",
+ "type": "__Card__:__snapshot_a94a8_test_47",
},
],
"removeAction": [],
@@ -2055,19 +2190,19 @@ describe('list bug', () => {
"flush": false,
"from": 0,
"to": 0,
- "type": "__Card__:__snapshot_a94a8_test_46",
+ "type": "__Card__:__snapshot_a94a8_test_47",
},
{
"flush": false,
"from": 1,
"to": 1,
- "type": "__Card__:__snapshot_a94a8_test_46",
+ "type": "__Card__:__snapshot_a94a8_test_47",
},
{
"flush": false,
"from": 2,
"to": 2,
- "type": "__Card__:__snapshot_a94a8_test_46",
+ "type": "__Card__:__snapshot_a94a8_test_47",
},
],
},
@@ -2085,7 +2220,7 @@ describe('list bug', () => {
"insertAction": [
{
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_46",
+ "type": "__Card__:__snapshot_a94a8_test_47",
},
],
"removeAction": [
@@ -2096,19 +2231,19 @@ describe('list bug', () => {
"flush": false,
"from": 0,
"to": 0,
- "type": "__Card__:__snapshot_a94a8_test_46",
+ "type": "__Card__:__snapshot_a94a8_test_47",
},
{
"flush": false,
"from": 1,
"to": 1,
- "type": "__Card__:__snapshot_a94a8_test_46",
+ "type": "__Card__:__snapshot_a94a8_test_47",
},
{
"flush": false,
"from": 2,
"to": 2,
- "type": "__Card__:__snapshot_a94a8_test_46",
+ "type": "__Card__:__snapshot_a94a8_test_47",
},
],
},
@@ -2133,13 +2268,13 @@ describe('list bug', () => {
"flush": false,
"from": 0,
"to": 0,
- "type": "__Card__:__snapshot_a94a8_test_46",
+ "type": "__Card__:__snapshot_a94a8_test_47",
},
{
"flush": false,
"from": 1,
"to": 1,
- "type": "__Card__:__snapshot_a94a8_test_46",
+ "type": "__Card__:__snapshot_a94a8_test_47",
},
],
},
@@ -2221,21 +2356,21 @@ describe('list-item JSXSpread', () => {
"item-key": "1",
"position": 0,
"recyclable": true,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
{
"full-span": true,
"item-key": "2",
"position": 1,
"recyclable": true,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
{
"full-span": true,
"item-key": "3",
"position": 2,
"recyclable": true,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
],
"removeAction": [],
@@ -2252,7 +2387,7 @@ describe('list-item JSXSpread', () => {
"item-key": "1",
"recyclable": false,
"to": 0,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
{
"flush": false,
@@ -2261,7 +2396,7 @@ describe('list-item JSXSpread', () => {
"item-key": "2",
"recyclable": false,
"to": 1,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
{
"flush": false,
@@ -2270,7 +2405,7 @@ describe('list-item JSXSpread', () => {
"item-key": "3",
"recyclable": false,
"to": 2,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
],
},
@@ -2300,21 +2435,21 @@ describe('list-item JSXSpread', () => {
"item-key": "1",
"position": 0,
"recyclable": true,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
{
"full-span": true,
"item-key": "2",
"position": 1,
"recyclable": true,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
{
"full-span": true,
"item-key": "3",
"position": 2,
"recyclable": true,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
],
"removeAction": [],
@@ -2331,7 +2466,7 @@ describe('list-item JSXSpread', () => {
"item-key": "1",
"recyclable": false,
"to": 0,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
{
"flush": false,
@@ -2340,7 +2475,7 @@ describe('list-item JSXSpread', () => {
"item-key": "2",
"recyclable": false,
"to": 1,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
{
"flush": false,
@@ -2349,7 +2484,7 @@ describe('list-item JSXSpread', () => {
"item-key": "3",
"recyclable": false,
"to": 2,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
],
},
@@ -2390,21 +2525,21 @@ describe('list-item JSXSpread', () => {
"item-key": "1",
"position": 0,
"recyclable": true,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
{
"full-span": true,
"item-key": "2",
"position": 1,
"recyclable": true,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
{
"full-span": true,
"item-key": "3",
"position": 2,
"recyclable": true,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
],
"removeAction": [],
@@ -2421,7 +2556,7 @@ describe('list-item JSXSpread', () => {
"item-key": "1",
"recyclable": false,
"to": 0,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
{
"flush": false,
@@ -2430,7 +2565,7 @@ describe('list-item JSXSpread', () => {
"item-key": "2",
"recyclable": false,
"to": 1,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
{
"flush": false,
@@ -2439,7 +2574,7 @@ describe('list-item JSXSpread', () => {
"item-key": "3",
"recyclable": false,
"to": 2,
- "type": "__Card__:__snapshot_a94a8_test_48",
+ "type": "__Card__:__snapshot_a94a8_test_49",
},
],
},
@@ -2562,7 +2697,7 @@ describe('list-item with platform info attributes', () => {
"reuse-identifier": "A",
"sticky-bottom": false,
"sticky-top": true,
- "type": "__Card__:__snapshot_a94a8_test_50",
+ "type": "__Card__:__snapshot_a94a8_test_51",
},
{
"estimated-height": 100,
@@ -2575,7 +2710,7 @@ describe('list-item with platform info attributes', () => {
"reuse-identifier": "A",
"sticky-bottom": false,
"sticky-top": false,
- "type": "__Card__:__snapshot_a94a8_test_50",
+ "type": "__Card__:__snapshot_a94a8_test_51",
},
{
"estimated-height": 100,
@@ -2588,7 +2723,7 @@ describe('list-item with platform info attributes', () => {
"reuse-identifier": "A",
"sticky-bottom": true,
"sticky-top": false,
- "type": "__Card__:__snapshot_a94a8_test_50",
+ "type": "__Card__:__snapshot_a94a8_test_51",
},
],
"removeAction": [],
@@ -2625,7 +2760,7 @@ describe('list-item with platform info attributes', () => {
"reuse-identifier": "A",
"sticky-bottom": false,
"sticky-top": true,
- "type": "__Card__:__snapshot_a94a8_test_50",
+ "type": "__Card__:__snapshot_a94a8_test_51",
},
{
"estimated-height": 100,
@@ -2638,7 +2773,7 @@ describe('list-item with platform info attributes', () => {
"reuse-identifier": "A",
"sticky-bottom": false,
"sticky-top": false,
- "type": "__Card__:__snapshot_a94a8_test_50",
+ "type": "__Card__:__snapshot_a94a8_test_51",
},
{
"estimated-height": 100,
@@ -2651,7 +2786,7 @@ describe('list-item with platform info attributes', () => {
"reuse-identifier": "A",
"sticky-bottom": true,
"sticky-top": false,
- "type": "__Card__:__snapshot_a94a8_test_50",
+ "type": "__Card__:__snapshot_a94a8_test_51",
},
],
"removeAction": [],
@@ -3126,7 +3261,7 @@ describe('list-item with "defer" attribute', () => {
{
"item-key": "1",
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_54",
+ "type": "__Card__:__snapshot_a94a8_test_55",
},
],
"removeAction": [],
@@ -3163,7 +3298,7 @@ describe('list-item with "defer" attribute', () => {
{
"item-key": "1",
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_54",
+ "type": "__Card__:__snapshot_a94a8_test_55",
},
],
"removeAction": [],
@@ -3256,17 +3391,17 @@ describe('list-item with "defer" attribute', () => {
{
"item-key": "0",
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_59",
+ "type": "__Card__:__snapshot_a94a8_test_60",
},
{
"item-key": "1",
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_60",
+ "type": "__Card__:__snapshot_a94a8_test_61",
},
{
"item-key": "2",
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_61",
+ "type": "__Card__:__snapshot_a94a8_test_62",
},
],
"removeAction": [],
@@ -3339,17 +3474,17 @@ describe('list-item with "defer" attribute', () => {
{
"item-key": "0",
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_59",
+ "type": "__Card__:__snapshot_a94a8_test_60",
},
{
"item-key": "1",
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_60",
+ "type": "__Card__:__snapshot_a94a8_test_61",
},
{
"item-key": "2",
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_61",
+ "type": "__Card__:__snapshot_a94a8_test_62",
},
],
"removeAction": [],
@@ -3420,17 +3555,17 @@ describe('list-item with "defer" attribute', () => {
{
"item-key": "0",
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_64",
+ "type": "__Card__:__snapshot_a94a8_test_65",
},
{
"item-key": "1",
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_64",
+ "type": "__Card__:__snapshot_a94a8_test_65",
},
{
"item-key": "2",
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_64",
+ "type": "__Card__:__snapshot_a94a8_test_65",
},
],
"removeAction": [],
@@ -3467,17 +3602,17 @@ describe('list-item with "defer" attribute', () => {
{
"item-key": "0",
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_64",
+ "type": "__Card__:__snapshot_a94a8_test_65",
},
{
"item-key": "1",
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_64",
+ "type": "__Card__:__snapshot_a94a8_test_65",
},
{
"item-key": "2",
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_64",
+ "type": "__Card__:__snapshot_a94a8_test_65",
},
],
"removeAction": [],
@@ -3526,17 +3661,17 @@ describe('list-item with "defer" attribute', () => {
{
"item-key": "0",
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_64",
+ "type": "__Card__:__snapshot_a94a8_test_65",
},
{
"item-key": "1",
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_64",
+ "type": "__Card__:__snapshot_a94a8_test_65",
},
{
"item-key": "2",
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_64",
+ "type": "__Card__:__snapshot_a94a8_test_65",
},
],
"removeAction": [],
@@ -3668,15 +3803,15 @@ describe('nested list', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_69",
+ "type": "__Card__:__snapshot_a94a8_test_70",
},
{
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_69",
+ "type": "__Card__:__snapshot_a94a8_test_70",
},
{
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_69",
+ "type": "__Card__:__snapshot_a94a8_test_70",
},
],
"removeAction": [],
@@ -3688,7 +3823,7 @@ describe('nested list', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_70",
+ "type": "__Card__:__snapshot_a94a8_test_71",
},
],
"removeAction": [],
@@ -3700,7 +3835,7 @@ describe('nested list', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_70",
+ "type": "__Card__:__snapshot_a94a8_test_71",
},
],
"removeAction": [],
@@ -3712,7 +3847,7 @@ describe('nested list', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_70",
+ "type": "__Card__:__snapshot_a94a8_test_71",
},
],
"removeAction": [],
@@ -3732,7 +3867,7 @@ describe('nested list', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_70",
+ "type": "__Card__:__snapshot_a94a8_test_71",
},
],
"removeAction": [],
@@ -3744,7 +3879,7 @@ describe('nested list', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_70",
+ "type": "__Card__:__snapshot_a94a8_test_71",
},
],
"removeAction": [],
@@ -3756,7 +3891,7 @@ describe('nested list', () => {
"insertAction": [
{
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_70",
+ "type": "__Card__:__snapshot_a94a8_test_71",
},
],
"removeAction": [],
@@ -3795,15 +3930,15 @@ describe('nested list', () => {
"insertAction": Array [
Object {
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_69",
+ "type": "__Card__:__snapshot_a94a8_test_70",
},
Object {
"position": 1,
- "type": "__Card__:__snapshot_a94a8_test_69",
+ "type": "__Card__:__snapshot_a94a8_test_70",
},
Object {
"position": 2,
- "type": "__Card__:__snapshot_a94a8_test_69",
+ "type": "__Card__:__snapshot_a94a8_test_70",
},
],
"removeAction": Array [],
@@ -3825,7 +3960,7 @@ describe('nested list', () => {
"insertAction": Array [
Object {
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_70",
+ "type": "__Card__:__snapshot_a94a8_test_71",
},
],
"removeAction": Array [],
@@ -3856,7 +3991,7 @@ describe('nested list', () => {
"insertAction": Array [
Object {
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_70",
+ "type": "__Card__:__snapshot_a94a8_test_71",
},
],
"removeAction": Array [],
@@ -3887,7 +4022,7 @@ describe('nested list', () => {
"insertAction": Array [
Object {
"position": 0,
- "type": "__Card__:__snapshot_a94a8_test_70",
+ "type": "__Card__:__snapshot_a94a8_test_71",
},
],
"removeAction": Array [],
diff --git a/packages/react/runtime/src/backgroundSnapshot.ts b/packages/react/runtime/src/backgroundSnapshot.ts
index 6f72835dc0..b1c6a51e22 100644
--- a/packages/react/runtime/src/backgroundSnapshot.ts
+++ b/packages/react/runtime/src/backgroundSnapshot.ts
@@ -471,6 +471,8 @@ export function hydrate(
(a, b) => {
helper(a, b);
},
+ // Should be `false` in hydrate as SerializedSnapshotInstance has no item-key
+ false,
);
diffArrayAction(
beforeChildNodes,
diff --git a/packages/react/runtime/src/hydrate.ts b/packages/react/runtime/src/hydrate.ts
index 322fbe6f91..077b514663 100644
--- a/packages/react/runtime/src/hydrate.ts
+++ b/packages/react/runtime/src/hydrate.ts
@@ -5,10 +5,13 @@
import { componentAtIndexFactory, enqueueComponentFactory, gRecycleMap, gSignMap } from './list.js';
import { __pendingListUpdates } from './pendingListUpdates.js';
import { DynamicPartType } from './snapshot/dynamicPartType.js';
+import type { PlatformInfo } from './snapshot/platformInfo.js';
import { unref } from './snapshot/ref.js';
import type { SnapshotInstance } from './snapshot.js';
import { isEmptyObject } from './utils.js';
+const UNREACHABLE_ITEM_KEY_NOT_FOUND = 'UNREACHABLE_ITEM_KEY_NOT_FOUND';
+
export interface DiffResult {
$$diff: true;
// insert No.j to new
@@ -21,6 +24,7 @@ export interface DiffResult {
export interface Typed {
type: string;
+ __listItemPlatformInfo?: PlatformInfo;
}
export function isEmptyDiffResult(diffResult: DiffResult): boolean {
@@ -34,6 +38,7 @@ export function diffArrayLepus(
after: B[],
isSameType: (a: A, b: B) => boolean,
onDiffChildren: (a: A, b: B, oldIndex: number, newIndex: number) => void,
+ isListHasItemKey: boolean,
): DiffResult {
let lastPlacedIndex = 0;
const result: DiffResult = {
@@ -46,12 +51,18 @@ export function diffArrayLepus(
for (let i = 0; i < before.length; i++) {
const node = before[i]!;
- (beforeMap[node.type] ??= new Set()).add([node, i]);
+ const key = isListHasItemKey
+ ? node.__listItemPlatformInfo?.['item-key'] ?? UNREACHABLE_ITEM_KEY_NOT_FOUND
+ : node.type;
+ (beforeMap[key] ??= new Set()).add([node, i]);
}
for (let i = 0; i < after.length; i++) {
const afterNode = after[i]!;
- const beforeNodes = beforeMap[afterNode.type];
+ const key = isListHasItemKey
+ ? afterNode.__listItemPlatformInfo?.['item-key'] ?? UNREACHABLE_ITEM_KEY_NOT_FOUND
+ : afterNode.type;
+ const beforeNodes = beforeMap[key];
let beforeNode: [A, number];
if (
@@ -258,6 +269,7 @@ export function hydrate(before: SnapshotInstance, after: SnapshotInstance, optio
(a, b) => {
hydrate(a, b, options);
},
+ false,
);
diffArrayAction(
beforeChildNodes,
@@ -341,6 +353,7 @@ export function hydrate(before: SnapshotInstance, after: SnapshotInstance, optio
}
}
},
+ true,
);
for (const i of diffResult.r) {