Open weekbin opened 7 months ago
用官网的例子改了改就可以复现。
/**
* title: Dynamic item height
* desc: Specify item height dynamically.
*
* title.zh-CN: 动态元素高度
* desc.zh-CN: 动态指定每个元素的高度
*/
import React, { useMemo, useRef } from 'react';
import { useVirtualList } from 'ahooks';
export default () => {
const containerRef = useRef(null);
const wrapperRef = useRef(null);
const originalList = useMemo(() => Array.from(Array(200).keys()), []);
const [value, onChange] = React.useState<number>(0);
const [list, scrollTo] = useVirtualList(originalList, {
containerTarget: containerRef,
wrapperTarget: wrapperRef,
itemHeight: (i) => (i % 2 === 0 ? 428 : 310),
overscan: 10,
});
return (
<div>
<div style={{ textAlign: 'right', marginBottom: 16 }}>
<input
style={{ width: 120 }}
placeholder="line number"
type="number"
value={value}
onChange={(e) => onChange(Number(e.target.value))}
/>
<button
style={{ marginLeft: 8 }}
type="button"
onClick={() => {
scrollTo(Number(value));
}}
>
scroll to
</button>
</div>
<div ref={containerRef} style={{ height: '300px', overflow: 'auto', background: 'black' }}>
<div ref={wrapperRef}>
{list.map((ele) => (
<div
style={{
height: ele.index % 2 === 0 ? 428 : 310,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
border: '1px solid #e8e8e8',
background: ele.index % 2 === 0 ? 'green' : 'red'
}}
key={ele.index}
>
Row: {ele.data+1} size: {ele.index % 2 === 0 ? 'small' : 'large'}
</div>
))}
</div>
</div>
</div>
);
};
let me try
当最后一个元素的高度比 Container 还高时,getOffset 的返回值会等于 list.length
在计算 visibleCount 时,会导致 getVisibleCount 的返回值为 -list.length
最终会导致 start = list.length,end = overscan,会取不到元素进行渲染。
建议在 getVisibleCount 返回时增加判断 endIndex - fromIndex < 0 ? 0 : endIndex - fromIndex, 这样在最后一个元素高度比 Contianer 还大时,仍然可以保证正常的渲染。