React中Map循环内使用react-window组件报错求助
问题排查与解决方案
核心错误原因
react-window List组件用法错误
FixedSizeList(即代码中的List)要求传入渲染函数作为子元素(或通过renderItem属性),而非直接放置DOM/组件。你直接把<Grid>放在<List>内部,导致React无法识别无效的子元素类型,触发"Element type is invalid"错误。错误的嵌套结构
在products.map中循环渲染AutoSizer和List,会为每个product生成独立的虚拟列表,既违背虚拟列表优化大量数据的初衷,也会导致多个列表实例的逻辑混乱。
修正后的代码示例
import AutoSizer from 'react-virtualized-auto-sizer' import { FixedSizeList as List } from 'react-window' // ... {!isRetrievingProducts && products?.length > 0 && ( <AutoSizer> {({ height, width }) => ( <List className="List" height={height} itemCount={products.length} // 用实际产品数量作为列表项总数 itemSize={150} // 根据ProductCard实际高度调整,示例值为150px width={width} > {({ index, style }) => { const product = products[index]; return ( <div style={style} key={product?.productCode || index}> <Grid component="div" container> <Grid component="div" item xl={10} lg={12} md={12} sm={12} xs={12}> <ProductCard productIndex={index} product={product} /> </Grid> </Grid> </div> ); }} </List> )} </AutoSizer> )}
关键修正点说明
- List子元素改为渲染函数:函数接收
index和style参数,style必须传递给列表项根元素,这是react-window实现虚拟滚动的核心依赖。 - itemCount设为products.length:让虚拟列表明确总渲染项数,而非固定值5。
- 移除products.map嵌套:仅保留一个AutoSizer和List实例,所有产品通过List的渲染函数统一渲染。
- 设置合理itemSize:需根据
ProductCard实际高度调整,确保虚拟滚动计算准确。
内容的提问来源于stack exchange,提问作者Joseph
相关产品推荐
相关产品推荐

