使用react-virtualized InfiniteLoader遇Unexpected token错误,求API调用示例
嘿,我来帮你搞定这两个问题——先解决那个烦人的Unexpected token错误,再给你一个能用InfiniteLoader调用API的完整示例!
先解决Unexpected Token错误
这个错误大概率是语法没转译或者代码拼写问题,你可以从这几个方向排查:
- 检查导入语句:你代码里写的
import { InfiniteLoader, List } from 'rea...'明显没写完,要确保是import { InfiniteLoader, List } from 'react-virtualized';,别漏写后面的字母 - 检查Babel配置:如果是用Create React App搭建的项目,一般自带的配置就能支持ES6+语法;但如果是自定义配置,要确保安装了
@babel/preset-react和@babel/preset-env,并且配置正确,这样箭头函数、解构这些语法才能被正常转译 - 排查代码语法错误:看看有没有漏写括号、逗号,或者用了旧版Babel不支持的语法(比如可选链
?.,如果是这种情况需要安装@babel/plugin-proposal-optional-chaining插件)
InfiniteLoader调用API的完整示例
下面是一个可以直接参考的完整示例,包含API调用、状态管理和InfiniteLoader的核心配置:
import React, { useState, useEffect } from 'react'; import { InfiniteLoader, List, AutoSizer } from 'react-virtualized'; // 替换成你的真实API请求函数 const fetchPaginatedData = async (startIndex, pageSize) => { // 这里模拟API请求,实际项目里换成你的接口地址 const response = await fetch(`https://your-api-url.com/items?start=${startIndex}&limit=${pageSize}`); if (!response.ok) throw new Error('数据加载失败'); const result = await response.json(); return result.data; // 假设API返回的数据数组在data字段里 }; const InfiniteScrollComponent = () => { const [listItems, setListItems] = useState([]); const [isLoading, setIsLoading] = useState(false); const [hasMoreData, setHasMoreData] = useState(true); const PAGE_SIZE = 20; // 每次加载的数据条数 // 加载更多数据的核心函数,InfiniteLoader会自动触发它 const loadMoreRows = async ({ startIndex, stopIndex }) => { if (isLoading || !hasMoreData) return; setIsLoading(true); try { const newItems = await fetchPaginatedData(startIndex, stopIndex - startIndex + 1); // 如果返回的数据不足一页,说明没有更多数据了 if (newItems.length < PAGE_SIZE) { setHasMoreData(false); } setListItems(prevItems => [...prevItems, ...newItems]); } catch (error) { console.error('加载失败:', error); // 这里可以加用户提示,比如弹出错误信息 } finally { setIsLoading(false); } }; // 判断指定索引的行是否已经加载完成 const isRowLoaded = ({ index }) => { return !!listItems[index]; // 如果对应索引有数据,说明已加载 }; // 渲染每一行的内容 const renderRow = ({ index, key, style }) => { const item = listItems[index]; // 如果数据还没加载,显示加载占位 if (!item) { return ( <div key={key} style={style} className="loading-row"> <span>加载中...</span> </div> ); } // 这里替换成你的行内容渲染逻辑 return ( <div key={key} style={style} className="list-item"> <h4>{item.title}</h4> <p>{item.content}</p> </div> ); }; return ( <div style={{ height: 'calc(100vh - 80px)', width: '100%' }}> {/* AutoSizer用来自动适配父容器的宽高 */} <AutoSizer> {({ height, width }) => ( <InfiniteLoader isRowLoaded={isRowLoaded} loadMoreRows={loadMoreRows} // rowCount要设成当前已有数据+待加载的数量,没有更多数据时就等于已有数据长度 rowCount={hasMoreData ? listItems.length + PAGE_SIZE : listItems.length} > {({ onRowsRendered, registerChild }) => ( <List ref={registerChild} width={width} height={height} rowCount={listItems.length} rowHeight={120} // 根据你的行高调整,也可以用动态行高 rowRenderer={renderRow} onRowsRendered={onRowsRendered} overscanRowCount={10} // 预加载可视区域外的行数,提升滚动体验 /> )} </InfiniteLoader> )} </AutoSizer> {/* 底部加载提示 */} {isLoading && ( <div className="loading-footer"> <span>正在加载更多...</span> </div> )} {!hasMoreData && !isLoading && ( <div className="end-footer"> <span>- 已加载全部数据 -</span> </div> )} </div> ); }; export default InfiniteScrollComponent;
关键配置说明
loadMoreRows:InfiniteLoader会在用户滚动到接近未加载区域时触发这个函数,参数里的startIndex和stopIndex是当前需要加载的行范围,你可以用这两个值计算分页参数isRowLoaded:用来告诉组件哪些行已经加载完成,避免重复请求数据rowCount:InfiniteLoader的rowCount要设置成“已有数据条数+待加载条数”,这样组件才知道还有更多数据需要加载;当没有更多数据时,就设成已有数据的总长度AutoSizer:自动适配父容器的宽高,不用手动设置List的尺寸,适合响应式场景
额外注意事项
- 记得给List设置合适的
rowHeight,如果行高不固定,可以用DynamicSizeList替代List - 处理API请求的错误情况,比如网络异常时给用户友好提示
- 如果你的API是按页码分页的,可以把
startIndex转换成页码:page = Math.floor(startIndex / PAGE_SIZE) + 1
内容的提问来源于stack exchange,提问作者Chetan
相关产品推荐
相关产品推荐

