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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:41:49