我正在使用 react-window 来呈现虚拟化列表。我创建了一个通用组件,因此很容易将每个列表虚拟化。
通用组件如下所示:
const itemData = useMemo(() => React.Children.toArray(children), [children]);
const contextValue = useMemo(() => ({ setRowHeight }), [setRowHeight]);
return (
<TableBody className={classNames(classes.root, className)} ref={rootRef} data-testid='virtualized-table-body' {...other}>
<InfiniteLoader ref={loaderRef} itemCount={totalCount} isItemLoaded={isItemLoaded} loadMoreItems={loadMoreItems}>
{({ onItemsRendered, ref }) => (
<VirtualizedTableContext.Provider value={contextValue}>
<VariableSizeList
itemCount={loadedCount}
height={height}
width='100%'
itemSize={getRowHeight}
ref={ref}
itemData={itemData}
estimatedItemSize={configuration.defaultVirtualizedRowHeight}
overscanCount={overscanCount}
onItemsRendered={onItemsRendered}
>
{VirtualizedRow}
</VariableSizeList>
</VirtualizedTableContext.Provider>
)}
</InfiniteLoader>
</TableBody>
);
如您所见,我将孩子作为 itemData 传递,而 VirtualizedRow 将执行以下操作:
const VirtualizedRow = memo(function VirtualizedRow(props: VirtualizedRowProps) {
const { index, style, data } = props;
return (
<div style={style}>
<VirtualizedChildWrapper index={index}>{data[index]}</VirtualizedChildWrapper>
</div>
);
}, areEqual);
我目前遇到的问题是,一个孩子发生了变化(可能选择了一个列表项),然后所有其他项目也将被重新渲染。由于无法记住儿童(参见:https ://gist.github.com/slikts/e224b924612d53c1b61f359cfb962c06 ),我真的不知道如何解决重新渲染问题。有任何想法吗?