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

React中使用Fetch出现data.slice is not a function问题求助

问题分析与解决方案

你遇到的data.slice is not a function错误核心原因很明确:fetch返回的是一个Promise对象,不是直接的JSON数组。你现在直接把Promise赋值给data,然后调用slice方法,而Promise根本没有这个方法,所以报错了。

具体问题拆解

  • fetch('url').then(res => res.json()) 是异步操作,它不会立即返回解析后的数组,而是返回一个Promise——这个Promise会在请求完成后才会resolve出实际的数组数据。
  • 你同步地对data(也就是Promise)调用slice和访问data.length,完全不符合异步操作的逻辑,自然会抛出错误。

修复方案(类组件版本)

你的代码是React类组件(用到了this.state),我们需要把异步请求放到生命周期方法里,比如componentDidMount,请求完成后把数据存入state,再基于state里的数据做分页计算。

修改后的完整代码如下:

class PhotoGallery extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      currentPage: 1,
      usersPerPage: 10,
      photos: [] // 新增state存储照片数据
    };
    this.handlePages = this.handlePages.bind(this);
  }

  componentDidMount() {
    // 组件挂载后发起异步请求
    fetch('https://jsonplaceholder.typicode.com/photos')
      .then(response => response.json())
      .then(photos => {
        // 请求成功后更新state,触发组件重新渲染
        this.setState({ photos });
      })
      .catch(error => {
        // 别忘了处理请求失败的情况
        console.error('获取照片数据失败:', error);
      });
  }

  handlePages(e) {
    // 分页切换逻辑:更新当前页码
    this.setState({ currentPage: Number(e.target.id) });
  }

  render() {
    const left = '<';
    const right = '>';
    const { currentPage, usersPerPage, photos } = this.state;
    
    // 数据未加载完成时显示加载提示
    if (photos.length === 0) {
      return <div>加载中...</div>;
    }

    // 基于state中的数组计算分页数据
    const lastIndex = currentPage * usersPerPage;
    const firstIndex = lastIndex - usersPerPage;
    const currentPhotos = photos.slice(firstIndex, lastIndex);
    
    const renderPhotos = currentPhotos.map((photo) => {
      return (
        <tr key={photo.id}>
          <td className="number">{photo.title}</td>
        </tr>
      );
    });

    const pageNumbers = [];
    for (let i = 1; i <= Math.ceil(photos.length / usersPerPage); i++) {
      pageNumbers.push(i);
    }

    const renderPagination = pageNumbers.map(number => {
      return (
        <li className="controls" key={number} id={number} onClick={this.handlePages}>
          {number}
        </li>
      );
    });

    return (
      <div>
        <table>
          <tbody>{renderPhotos}</tbody>
        </table>
        <ul>{renderPagination}</ul>
      </div>
    );
  }
}

关键修改点说明

  1. 新增state存储数据:添加photos: []到state,专门保存fetch获取到的数组数据。
  2. 异步请求放到componentDidMount:组件挂载后发起请求,请求完成后通过setState更新数据,触发组件重新渲染。
  3. 添加加载状态判断:在photos为空时显示加载提示,避免数据未加载完成时执行分页逻辑导致错误。
  4. 基于state中的photos做分页:现在photos是实际的数组,所以可以正常调用slice和访问length了。

如果你更习惯用async/await,也可以把componentDidMount改成异步函数,代码会更简洁:

async componentDidMount() {
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/photos');
    const photos = await response.json();
    this.setState({ photos });
  } catch (error) {
    console.error('获取照片数据失败:', error);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:39:40