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

react-window:列表项变更时如何更新itemSize?过滤出现间隙

解决方案

你的问题核心是VariableSizeList会缓存列表项的高度值,当过滤导致navigation数组变化后,旧的高度缓存和新数据不匹配,从而出现布局间隙。以下是修复步骤:

1. 通过Ref获取列表实例

函数组件中不能直接通过resetAfterIndex属性重置缓存,需要先获取VariableSizeList的实例引用:

const listRef = useRef<VariableSizeList>(null);

2. 监听数据变化,重置高度缓存

当navigation数据更新时,调用实例的resetAfterIndex(0)方法,清除从第0项开始的所有高度缓存,让组件重新计算每个列表项的高度:

useEffect(() => {
  if (listRef.current) {
    listRef.current.resetAfterIndex(0);
  }
}, [navigation]);

3. 修改后的完整代码

const Row = memo(function Row({
  index,
  style,
  data: { navigation },
}: ListChildComponentProps<{
  navigation: Navigation[];
}>) {
  const nav = navigation[index];

  return (
    <li key={nav.name} style={style}>
      <h3>{nav.name}</h3>
      {nav.children.map((child) => (
          <Link key={child.name} href="#">
            {child.name}
          </Link>
        ))}
    </li>
  );
}, areEqual);


const getItemHeight = ({ navSection }: { navSection: Navigation }) => {
  return 36 + navSection.children.length * 36;
};


function List() {
  const { navigation } = useContext(NavigationContext);
  const listRef = useRef<VariableSizeList>(null);

  const getItemSize = useCallback((index: number) => getItemHeight({ navSection: navigation[index] }), [navigation]);
  const getItemLength = useMemo(() => navigation.length, [navigation]);

  useEffect(() => {
    if (listRef.current) {
      listRef.current.resetAfterIndex(0);
    }
  }, [navigation]);

  return (
    <AutoSizer>
      {({ height, width }: Size) => (
        <VariableSizeList
          ref={listRef}
          className="scrollbar"
          height={height}
          itemCount={getItemLength}
          itemSize={getItemSize}
          width={width}
          itemData={{ navigation }}
        >
          {Row}
        </VariableSizeList>
      )}
    </AutoSizer>
  );
}

关键说明

  • useCallback本身的写法没问题,但VariableSizeList不会自动检测itemSize函数的变化来清除缓存,必须手动触发重置
  • 你之前尝试的resetAfterIndex属性是类组件的用法,函数组件需要通过实例方法调用
  • 调用resetAfterIndex(0)会重置所有列表项的高度缓存,确保过滤后的新列表能正确计算每一行的高度

内容的提问来源于stack exchange,提问作者wongx

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:33:13