InfiniteScroll 不断获取数据,直到超出最大更新深度

问题描述 投票:0回答:1

在我的 React 项目中,当用户滚动到页面底部时,我使用 React-infinite-scroller 从 API 获取数据。页面加载时,第一个 fetch 调用按预期工作,但一旦我向下滚动,就会进行 50 多个 API 调用,并且出现

Maximum update depth exceeded
错误。关于我可能做错了什么有什么想法吗?

当 page=2 时,

response.data.next
null
,但从我看来,
hasMore
始终是
true

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

尝试使用

useRef
代替
useState
来代替
hasMore
,但结果是相同的。

我正在遵循一个如下所示的基本示例:

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;
reactjs infinite-scroll
1个回答
0
投票

问题出在您处理页面的方式上。 Infinity Scroll 首先调用

loadMore
,当您通过设置页面更改状态时,react 会触发重新渲染,当它重新渲染时,Infinity Scroll 再次调用
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;
© www.soinside.com 2019 - 2024. All rights reserved.