Skip to content

Commit d06ed5c

Browse files
committed
fix id mapping
1 parent d3aa289 commit d06ed5c

File tree

3 files changed

+31
-25
lines changed

3 files changed

+31
-25
lines changed

examples/animate.tsx

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ let uuid = 0;
99
function genItem() {
1010
uuid += 1;
1111
return {
12-
id: uuid,
12+
id: `key_${uuid}`,
13+
uuid,
1314
};
1415
}
1516

@@ -19,22 +20,23 @@ for (let i = 0; i < 19; i += 1) {
1920
}
2021

2122
interface Item {
22-
id: number;
23+
id: string;
24+
uuid: number;
2325
}
2426

2527
interface MyItemProps extends Item {
2628
visible: boolean;
27-
onClose: (id: number) => void;
28-
onLeave: (id: number) => void;
29-
onInsertBefore: (id: number) => void;
30-
onInsertAfter: (id: number) => void;
29+
onClose: (id: string) => void;
30+
onLeave: (id: string) => void;
31+
onInsertBefore: (id: string) => void;
32+
onInsertAfter: (id: string) => void;
3133
}
3234

3335
const getCurrentHeight = (node: HTMLElement) => ({ height: node.offsetHeight });
3436
const getCollapsedHeight = () => ({ height: 0, opacity: 0 });
3537

3638
const MyItem: React.FC<MyItemProps> = (
37-
{ id, visible, onClose, onLeave, onInsertBefore, onInsertAfter },
39+
{ id, uuid, visible, onClose, onLeave, onInsertBefore, onInsertAfter },
3840
ref,
3941
) => {
4042
return (
@@ -50,7 +52,7 @@ const MyItem: React.FC<MyItemProps> = (
5052
>
5153
{({ className, style }, motionRef) => (
5254
<div ref={motionRef} className={classNames('item', className)} style={style}>
53-
<div style={{ height: id % 2 ? 100 : undefined }}>
55+
<div style={{ height: uuid % 2 ? 100 : undefined }}>
5456
<button
5557
onClick={() => {
5658
onClose(id);
@@ -86,24 +88,24 @@ const Demo = () => {
8688
const [dataSource, setDataSource] = React.useState(originDataSource);
8789
const [closeMap, setCloseMap] = React.useState<{ [id: number]: boolean }>({});
8890

89-
const onClose = (id: number) => {
91+
const onClose = (id: string) => {
9092
setCloseMap({
9193
...closeMap,
9294
[id]: true,
9395
});
9496
};
9597

96-
const onLeave = (id: number) => {
98+
const onLeave = (id: string) => {
9799
const newDataSource = dataSource.filter(item => item.id !== id);
98100
setDataSource(newDataSource);
99101
};
100102

101-
const onInsertBefore = (id: number) => {
103+
const onInsertBefore = (id: string) => {
102104
const index = dataSource.findIndex(item => item.id === id);
103105
const newDataSource = [...dataSource.slice(0, index), genItem(), ...dataSource.slice(index)];
104106
setDataSource(newDataSource);
105107
};
106-
const onInsertAfter = (id: number) => {
108+
const onInsertAfter = (id: string) => {
107109
const index = dataSource.findIndex(item => item.id === id) + 1;
108110
const newDataSource = [...dataSource.slice(0, index), genItem(), ...dataSource.slice(index)];
109111
setDataSource(newDataSource);

src/List.tsx

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -82,21 +82,20 @@ class List<T> extends React.Component<ListProps<T>, ListState> {
8282
if (status === 'MEASURE_START') {
8383
// Record here since measure item height will get warning in `render`
8484
for (let index = startIndex; index <= endIndex; index += 1) {
85-
const item = dataSource[index];
86-
const eleKey = itemKey ? item[itemKey] : index;
87-
this.itemElementHeights[index] = getNodeHeight(this.itemElements[eleKey]);
85+
const eleKey = this.getItemKey(index);
86+
this.itemElementHeights[eleKey] = getNodeHeight(this.itemElements[eleKey]);
8887
}
8988

9089
// Calculate top visible item top offset
91-
const locatedItemHeight = this.getItemHeight(itemIndex);
90+
const locatedItemHeight = this.itemElementHeights[this.getItemKey(itemIndex)] || 0;
9291
const locatedItemTop = scrollPtg * this.listRef.current.clientHeight;
9392
const locatedItemOffset = itemOffsetPtg * locatedItemHeight;
9493
const locatedItemMergedTop =
9594
this.listRef.current.scrollTop + locatedItemTop - locatedItemOffset;
9695

9796
let startItemTop = locatedItemMergedTop;
9897
for (let index = itemIndex - 1; index >= startIndex; index -= 1) {
99-
startItemTop -= this.getItemHeight(index);
98+
startItemTop -= this.itemElementHeights[this.getItemKey(index)] || 0;
10099
}
101100

102101
this.setState({ status: 'MEASURE_DONE', startItemTop });
@@ -108,8 +107,6 @@ class List<T> extends React.Component<ListProps<T>, ListState> {
108107
}
109108
}
110109

111-
public getItemHeight = (index: number) => this.itemElementHeights[index] || 0;
112-
113110
/**
114111
* Phase 2: Trigger render since we should re-calculate current position.
115112
*/
@@ -142,16 +139,21 @@ class List<T> extends React.Component<ListProps<T>, ListState> {
142139
});
143140
};
144141

142+
public getItemKey = (index: number) => {
143+
const { dataSource, itemKey } = this.props;
144+
const item = dataSource[index];
145+
return item && itemKey ? item[itemKey] : index;
146+
};
147+
145148
/**
146149
* Phase 4: Render item and get all the visible items height
147150
*/
148-
public renderChildren = (list: T[], startIndex: number, renderFunc: RenderFunc<T>) => {
149-
const { itemKey } = this.props;
151+
public renderChildren = (list: T[], startIndex: number, renderFunc: RenderFunc<T>) =>
150152
// We should measure rendered item height
151-
return list.map((item, index) => {
153+
list.map((item, index) => {
152154
const node = renderFunc(item) as React.ReactElement;
153155
const eleIndex = startIndex + index;
154-
const eleKey = itemKey ? item[itemKey] : eleIndex;
156+
const eleKey = this.getItemKey(eleIndex);
155157

156158
// Pass `key` and `ref` for internal measure
157159
return React.cloneElement(node, {
@@ -160,8 +162,8 @@ class List<T> extends React.Component<ListProps<T>, ListState> {
160162
this.itemElements[eleKey] = ele;
161163
},
162164
});
163-
});
164-
};
165+
})
166+
;
165167

166168
public render() {
167169
const {

src/util.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,5 @@ export function getNodeHeight(node: HTMLElement) {
4747

4848
return findDOMNode(node).offsetHeight;
4949
}
50+
51+
export function getStartItemTop(itemIndex: number) {}

0 commit comments

Comments
 (0)