You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React-Virtualized排序数据后行高未更新问题求助

解决react-virtualized排序后行高不更新的问题

问题根源在于CellMeasurerCache是通过**行索引(rowIndex)**缓存行高的。排序后,原索引对应的数据发生了变化,但缓存里的行高还是旧索引关联的值,导致新数据无法触发重新测量行高。

解决步骤:

  1. 清空缓存:每次排序后调用缓存的clearAll()方法,清除旧的行高缓存,让组件重新计算每个行的高度。
  2. 使用稳定的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 06:40:35