在我的React项目中,当用户滚动到页面底部时,我使用react-infinite-scroll从API获取数据.当页面加载时,第一个获取调用按预期工作,但只要我向下滚动,就会进行50多个API调用,并得到Maximum update depth exceeded错误.你知道我可能做错了什么吗?

当页面=2时,response.data.next就是null,但从我的Angular 来看,hasMore总是true.

{"count":6,"next":null,...}

try 对hasMore使用useRef而不是useState,但结果相同.

我正在遵循一个基本示例,看起来像这样:

import React, { useState, useEffect } from 'react';
import InfiniteScroll from 'react-infinite-scroller';
import Box from '@mui/material/Box';
import axiosInstance from '../axios';

const Test = () => {
  const [data, setData] = useState([]);
  const [hasMore, setHasMore] = useState(true);
  const [page, setPage] = useState(1);

  const fetchData = async (pageNumber) => {
    try {
      const response = await axiosInstance.get("/search/?page=" + (page))
      const newData = response.data.results;
      setData(prevData => [...prevData, ...newData]);
      setHasMore(response.data.next !== null);
    } catch (error) {
      console.error('Error fetching data:', error);
    }
  };

  useEffect(() => {
    fetchData(page);
  }, [page]);

  const loadMore = () => {
    setPage(prevPage => prevPage + 1);
  };

  return (
    <>
    <Box sx={{height: '800px'}}>

    </Box>
    <InfiniteScroll
      pageStart={0}
      loadMore={loadMore}
      hasMore={hasMore}
      loader={<div key={0}>Loading...</div>}
    >
      {data.map(item => (
        <div key={item.id}>
          {/* Render your data here */}
        </div>
      ))}
    </InfiniteScroll>
    </>
  );
};

export default Test;

推荐答案

问题在于您处理页面号的方式.Infinity Scroll从调用loadMore开始,因为您正在通过设置页面号来改变状态,reaction触发重新渲染,当它被重新渲染时,如果Infinity Scroll没有元素,它会再次调用loadMore,因为Infinity Scroll只会在API调用后获取元素,它会在每次重新渲染中不断调用loadMore,当loadMore触发重新渲染时,它会导致无限重新渲染循环.

可能有更多方法可以解决这个问题,但用Ref而不是State处理页面号可以解决这个问题:

import React, { useState } from 'react';
import InfiniteScroll from 'react-infinite-scroller';
import Box from '@mui/material/Box';
import axiosInstance from '../axios';

const Test = () => {
  const [data, setData] = useState([]);
  const [hasMore, setHasMore] = useState(true);
  const page = useRef(1);

  const fetchData = async (pageNumber) => {
    try {
      const response = await axiosInstance.get("/search/?page=" + pageNumber);
      const newData = response.data.results;
      setData(prevData => [...prevData, ...newData]);
      setHasMore(response.data.next !== null);
    } catch (error) {
      console.error('Error fetching data:', error);
    }
  };

  const loadMore = () => {
    fetchData(page.current++);
  };

  return (
    <>
    <Box sx={{height: '800px'}}>

    </Box>
    <InfiniteScroll
      pageStart={0}
      loadMore={loadMore}
      hasMore={hasMore}
      loader={<div key={0}>Loading...</div>}
    >
      {data.map(item => (
        <div key={item.id}>
          {/* Render your data here */}
        </div>
      ))}
    </InfiniteScroll>
    </>
  );
};

export default Test;

Reactjs相关问答推荐

如何使用json将购物车数组传递到后台API

如何等待我的插入内容提交后再继续执行指令?

为什么Next.js 14无法解析页面路由路径?

Npm运行构建`在Next.js 14中不起作用

更改购物车中的产品数量后,PayPal Reaction/Next JS按钮未更新

无法将react 路由状态从路由传递给子组件

为什么查询错误在处理后仍出现在控制台中?RTK查询+ React

如何使ionic 面包屑在州政府条件下可点击?

如何在MUI x图表条形图上放置圆角?

React 错误无法读取未定义的属性(读取id)#react

画布:用鼠标绘制形状时重新绘制整个画布会导致卡顿

在React Router 6中,在路由渲染后更新路由数据

每次状态更改时都会提交react 表单

Material UI @mui/material/Button vs @material-ui/core/Button,它什么时候改变的,旧版本的文档在哪里

使用登录保护 React 中的 SPA 应用程序 - 为什么这种方法不起作用?

如何使用 React Hook Form 将寄存器作为 props 发送到子组件来收集数据?

当我在 useEffect 中使用 useDispatch 时,我的组件继续渲染

如何通过 Material ui select 使下拉菜单下拉

如何在 v6.4 中将 Auth0 提供程序与新的 createBrowsereRouter 一起使用?

将 C# Razor 条件块转换为 React.js 代码