Skip to content

Commit fabfee8

Browse files
committed
add mulitple mark to check if multiple content diff
1 parent d7d5b7b commit fabfee8

File tree

3 files changed

+72
-26
lines changed

3 files changed

+72
-26
lines changed

src/List.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,11 @@ class List<T> extends React.Component<ListProps<T>, ListState<T>> {
177177
const { data, height, itemHeight, disabled, onSkipRender } = this.props;
178178
const prevData: T[] = this.cachedProps.data || [];
179179

180-
const changedItemIndex: number =
181-
prevData.length !== data.length ? findListDiffIndex(prevData, data, this.getItemKey) : null;
180+
let changedItemIndex: number = null;
181+
if (prevData.length !== data.length) {
182+
const diff = findListDiffIndex(prevData, data, this.getItemKey);
183+
changedItemIndex = diff ? diff.index : null;
184+
}
182185

183186
if (disabled) {
184187
// Should trigger `onSkipRender` to tell that diff component is not render in the list

src/utils/algorithmUtil.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,17 @@ export function findListDiffIndex<T>(
4040
originList: T[],
4141
targetList: T[],
4242
getKey: (item: T) => string,
43-
): number | null {
43+
): { index: number; multiple: boolean } | null {
4444
const originLen = originList.length;
4545
const targetLen = targetList.length;
4646

47-
// Skip if more than 1 content is diff
48-
if (Math.abs(originLen - targetLen) !== 1) {
49-
return null;
50-
}
51-
5247
let shortList: T[];
5348
let longList: T[];
5449

50+
if (originLen === 0 && targetLen === 0) {
51+
return null;
52+
}
53+
5554
if (originLen < targetLen) {
5655
shortList = originList;
5756
longList = targetList;
@@ -62,23 +61,25 @@ export function findListDiffIndex<T>(
6261

6362
const notExistKey = { __EMPTY_ITEM__: true };
6463
function getItemKey(item: T) {
65-
if (item) {
64+
if (item !== undefined) {
6665
return getKey(item);
6766
}
6867
return notExistKey;
6968
}
7069

7170
// Loop to find diff one
72-
let diffIndex = 0;
71+
let diffIndex: number = null;
72+
let multiple = Math.abs(originLen - targetLen) !== 1;
7373
for (let i = 0; i < longList.length; i += 1) {
7474
const shortKey = getItemKey(shortList[i]);
7575
const longKey = getItemKey(longList[i]);
7676

7777
if (shortKey !== longKey) {
78-
diffIndex = shortKey === getItemKey(longList[i + 1]) ? i : null;
78+
diffIndex = i;
79+
multiple = multiple || shortKey !== getItemKey(longList[i + 1]);
7980
break;
8081
}
8182
}
8283

83-
return diffIndex;
84+
return diffIndex === null ? null : { index: diffIndex, multiple };
8485
}

tests/util.test.js

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,10 @@ describe('Util', () => {
5353
const targetList = originList.slice();
5454
targetList.splice(diff, 1);
5555

56-
expect(findListDiffIndex(originList, targetList, num => num)).toEqual(diff);
56+
expect(findListDiffIndex(originList, targetList, num => num)).toEqual({
57+
index: diff,
58+
multiple: false,
59+
});
5760
});
5861
}
5962

@@ -69,7 +72,10 @@ describe('Util', () => {
6972
const targetList = originList.slice();
7073
targetList.splice(diff, 0, 'NEW_ITEM');
7174

72-
expect(findListDiffIndex(originList, targetList, num => num)).toEqual(diff);
75+
expect(findListDiffIndex(originList, targetList, num => num)).toEqual({
76+
index: diff,
77+
multiple: false,
78+
});
7379
});
7480
}
7581

@@ -84,21 +90,57 @@ describe('Util', () => {
8490
});
8591

8692
it('small list', () => {
87-
expect(findListDiffIndex([0], [], num => num)).toEqual(0);
88-
expect(findListDiffIndex([0, 1], [0], num => num)).toEqual(1);
89-
expect(findListDiffIndex([0, 1, 2], [0], num => num)).toEqual(null);
90-
expect(findListDiffIndex([], [0], num => num)).toEqual(0);
91-
expect(findListDiffIndex([0], [0, 1], num => num)).toEqual(1);
93+
expect(findListDiffIndex([0], [], num => num)).toEqual({
94+
index: 0,
95+
multiple: false,
96+
});
97+
expect(findListDiffIndex([0, 1], [0], num => num)).toEqual({
98+
index: 1,
99+
multiple: false,
100+
});
101+
expect(findListDiffIndex([0, 1, 2], [0], num => num)).toEqual({
102+
index: 1,
103+
multiple: true,
104+
});
105+
expect(findListDiffIndex([], [0], num => num)).toEqual({
106+
index: 0,
107+
multiple: false,
108+
});
109+
expect(findListDiffIndex([0], [0, 1], num => num)).toEqual({
110+
index: 1,
111+
multiple: false,
112+
});
92113
});
93114

94115
it('diff only 1', () => {
95-
expect(findListDiffIndex([0, 1, 2], [], num => num)).toEqual(null);
96-
expect(findListDiffIndex([0, 1, 2], [1, 2], num => num)).toEqual(0);
97-
expect(findListDiffIndex([0, 1, 2], [0, 2], num => num)).toEqual(1);
98-
expect(findListDiffIndex([0, 1, 2], [0, 1], num => num)).toEqual(2);
99-
expect(findListDiffIndex([0, 1, 2], [0], num => num)).toEqual(null);
100-
expect(findListDiffIndex([0, 1, 2], [1], num => num)).toEqual(null);
101-
expect(findListDiffIndex([0, 1, 2], [2], num => num)).toEqual(null);
116+
expect(findListDiffIndex([0, 1, 2], [], num => num)).toEqual({
117+
index: 0,
118+
multiple: true,
119+
});
120+
expect(findListDiffIndex([0, 1, 2], [1, 2], num => num)).toEqual({
121+
index: 0,
122+
multiple: false,
123+
});
124+
expect(findListDiffIndex([0, 1, 2], [0, 2], num => num)).toEqual({
125+
index: 1,
126+
multiple: false,
127+
});
128+
expect(findListDiffIndex([0, 1, 2], [0, 1], num => num)).toEqual({
129+
index: 2,
130+
multiple: false,
131+
});
132+
expect(findListDiffIndex([0, 1, 2], [0], num => num)).toEqual({
133+
index: 1,
134+
multiple: true,
135+
});
136+
expect(findListDiffIndex([0, 1, 2], [1], num => num)).toEqual({
137+
index: 0,
138+
multiple: true,
139+
});
140+
expect(findListDiffIndex([0, 1, 2], [2], num => num)).toEqual({
141+
index: 0,
142+
multiple: true,
143+
});
102144
});
103145
});
104146
});

0 commit comments

Comments
 (0)