React实现加载更多分页:如何将新数组追加至已有状态数组?
React加载更多分页:正确追加列表数据的解决方案
核心问题拆解
- 状态引用修改问题:直接赋值
tempObj = postparem是引用传递,修改属性后React无法检测到状态变更,必须创建新对象。 - 异步时序错误:调用
getProductChildMenu后立即更新copyMenu,此时新数据还未返回,拿到的仍是旧值。 - 数组追加方式错误:
setCopyMenu(...copyMenu, productChildMenu)会把整个新数组作为单个元素插入,导致二维数组,无法被map正常遍历。
修正后的实现方案
方案1:基于异步请求返回值直接更新(推荐)
如果getProductChildMenu返回Promise,直接等待请求结果后追加数据:
const handleLoadMoreClick = async () => { // 1. 正确更新分页参数:创建新对象,避免修改原状态引用 const newParams = { ...postparem, pagenumber: postparem.pagenumber + 1 }; setPostparem(newParams); // 2. 等待请求返回新数据 const newProductList = await getProductChildMenu(APIProductList, newParams); // 3. 追加新数据:展开新旧数组的每一项,合并成一维数组 setCopyMenu(prevMenu => [...prevMenu, ...newProductList]); };
方案2:基于状态监听更新(适配请求后更新状态的场景)
如果getProductChildMenu是通过更新productChildMenu状态来返回数据,用useEffect监听状态变化:
import { useEffect } from 'react'; // 监听productChildMenu变化,追加到copyMenu useEffect(() => { // 排除初始加载的第一页数据,避免重复添加 if (postparem.pagenumber > 1) { setCopyMenu(prevMenu => [...prevMenu, ...productChildMenu]); } }, [productChildMenu, postparem.pagenumber]); const handleLoadMoreClick = () => { // 更新分页参数 const newParams = { ...postparem, pagenumber: postparem.pagenumber + 1 }; setPostparem(newParams); // 触发请求 getProductChildMenu(APIProductList, newParams); };
额外优化:防止重复点击与无数据提示
添加加载状态,避免用户频繁触发请求,并处理无更多数据的场景:
import { useState } from 'react'; const [isLoading, setIsLoading] = useState(false); const handleLoadMoreClick = async () => { if (isLoading) return; setIsLoading(true); try { const newParams = { ...postparem, pagenumber: postparem.pagenumber + 1 }; setPostparem(newParams); const newProductList = await getProductChildMenu(APIProductList, newParams); if (newProductList.length === 0) { alert('已加载全部数据'); return; } setCopyMenu(prevMenu => [...prevMenu, ...newProductList]); } catch (error) { console.error('加载失败:', error); } finally { setIsLoading(false); } };
内容的提问来源于stack exchange,提问作者Shreyas Agarwal
相关产品推荐
相关产品推荐

