React-Virtualized排序数据后行高未更新问题求助
解决react-virtualized排序后行高不更新的问题
问题根源在于CellMeasurerCache是通过**行索引(rowIndex)**缓存行高的。排序后,原索引对应的数据发生了变化,但缓存里的行高还是旧索引关联的值,导致新数据无法触发重新测量行高。
解决步骤:
- 清空缓存:每次排序后调用缓存的
clearAll()方法,清除旧的行高缓存,让组件重新计算每个行的高度。 - 使用稳定的key:将行渲染的key从默认的index改为数据的唯一id,避免React因索引变化复用错误的组件实例,确保行高测量准确。
修改后的完整代码:
export default function App() { const cache = React.useRef( new CellMeasurerCache({ fixedWidth: true, defaultHeight: 100, }) ); const [people, setPeople] = React.useState([]); React.useEffect(() => { setPeople( [...Array(1000).keys()].map((key) => { return { id: key, name: `${faker.name.firstName()} ${faker.name.lastName()}`, bio: faker.lorem.lines(Math.random() * 100), }; }) ); }, []); const ascending = () => { const sorted = [...people].sort((a, b) => a.name.localeCompare(b.name)); setPeople(sorted); cache.current.clearAll(); // 清空缓存,触发重新测量 }; const decending = () => { const sorted = [...people].sort((a, b) => b.name.localeCompare(a.name)); setPeople(sorted); cache.current.clearAll(); // 清空缓存,触发重新测量 }; return ( <div> <button onClick={ascending}>ascending</button> <button onClick={decending}>decending</button> <div style={{ width: "100%", height: "100vh" }}> <AutoSizer> {({ width, height }) => ( <List width={width} height={height} rowHeight={cache.current.rowHeight} deferredMeasurementCache={cache.current} rowCount={people.length} rowRenderer={({ index, style, parent }) => { const person = people[index]; // 使用数据id作为key,确保组件复用正确 return ( <CellMeasurer key={person.id} cache={cache.current} parent={parent} columnIndex={0} rowIndex={index} > <div style={style}> <h2>{person.name}</h2> <p>{person.bio}</p> </div> </CellMeasurer> ); }} /> )} </AutoSizer> </div> </div> ); }
补充说明:
clearAll()方法会清除缓存中所有行的高度记录,之后List会重新通过CellMeasurer测量每个行的实际高度。- 使用数据的唯一id作为key,避免排序后React根据索引复用旧的行组件,确保每个行都能重新计算高度。
内容的提问来源于stack exchange,提问作者Sajib Hossain
相关产品推荐
相关产品推荐

