React InfiniteScroll组件加载异常无限渲染问题修复方案
react-infinite-scroll 加载异常、无限渲染问题修复
两个异常的核心原因
- 写
next={fetchDataOnScroll()}导致页面卡死:你传入的是函数立即执行的结果而非函数引用,组件每次渲染都会立刻执行请求,请求完成更新state触发重渲染,重渲染又再次执行请求,进入死循环。next属性必须传入函数引用本身,不能加调用括号。 - 传函数引用时一直显示LOADING、无法加载内容:代码里存在3个直接阻断逻辑运行的bug:
- 接口返回判断逻辑缺少
if关键字,(res.data.doc.length === 0) setHasMore(false)属于非法语法,会直接中断fetch函数执行,请求后续的更新状态逻辑完全不会运行。 - 存在闭包陷阱:fetch函数里直接读取外层的
pageNumber状态,组件触发滚动加载时拿到的永远是初始页码1,每次请求都拉取第一页数据,页码更新不会同步到触发的加载函数中,导致加载逻辑紊乱。 - 错误捕获逻辑的对象路径写反:axios报错的结构是
error.response.data,你写的error.data.response会在请求出错时抛出二次错误,吞掉真实的报错信息,根本无法定位接口问题。
- 接口返回判断逻辑缺少
修复后可直接运行的代码
import { useState } from 'react' import axios from 'axios' import InfiniteScroll from 'react-infinite-scroll-component' import FeedCard from './FeedCard' export default function PostList() { const [posts, setPosts] = useState([]) const [hasMore, setHasMore] = useState(true) const [pageNumber, setPageNumber] = useState(1) // 新增加载锁,防止重复触发请求 const [loading, setLoading] = useState(false) const fetchDataOnScroll = async () => { // 加载中直接返回,避免重复请求 if (loading) return try { setLoading(true) const res = await axios.get( `${process.env.REACT_APP_API}/api/v1/posts?page=${pageNumber}` ) const newPosts = res.data.doc if (newPosts.length === 0) { setHasMore(false) } else { setPosts((prev) => [...prev, ...newPosts]) setPageNumber((prev) => prev + 1) } } catch (error) { alert('Error fetching Posts') // 修正错误打印路径 console.log('ERROR', error?.response?.data) } finally { setLoading(false) } } return ( <InfiniteScroll hasMore={hasMore} next={fetchDataOnScroll} endMessage={<p style={{ textAlign: 'center' }}>No More Post</p>} dataLength={posts.length} loader={<h1>LOADING...</h1>} > {posts.map((post) => ( <FeedCard key={post._id} post={post} /> ))} </InfiniteScroll> ) }
额外注意事项
- 如果你的列表是在固定高度的容器内滚动,不是全局window滚动,必须给
InfiniteScroll组件添加scrollableTarget属性,传入滚动容器的id,否则组件找不到正确的滚动监听对象,会一直卡在加载状态。 - 初始加载时如果posts为空导致容器高度不足,组件会自动触发第一次拉取,不需要额外在
useEffect中手动调用fetch函数。 - 接口返回的新数据长度如果小于你后端设置的单页条数,也要同步设置
hasMore为false,避免后续无效触发。
内容的提问来源于stack exchange,提问作者merlin
相关产品推荐
相关产品推荐

