React分页加载时新数据追加失败怎么办?
我在做一个商品列表分页,用useState存数据和页码,滚动到底部触发fetch请求。但第二次加载时新数据覆盖了旧数据而不是追加,控制台没报错,这是为什么呢?
const [items, setItems] = useState([]);
const [page, setPage] = useState(1);
useEffect(() => {
const fetchMore = async () => {
const res = await API.get(`/products?page=${page}`);
setItems(res.data); // 这里是不是应该用函数式更新?
};
fetchMore();
}, [page]);
const handleScroll = () => {
if (nearBottom) setPage(prev => prev + 1);
};
我试过把setItems写成setItems(prev => […prev, …res.data]),但这样每次刷新页面页码会重置,导致重复请求第一页的数据。有没有更好的状态管理方式?
你提到用setItems(prev => [...prev, ...res.data]),这其实是对的,但你说“每次刷新页面页码会重置,导致重复请求第一页的数据”,说明你可能在切换页面或组件卸载时没有重置状态。解决办法是在组件卸载时手动重置items和page。
另外,你在useEffect里面依赖page变化来触发fetchMore,这也没问题,但你得确保每次组件渲染时useEffect里面拿到的都是最新状态。
一个更清晰的做法是:
然后在你监听滚动事件的地方:
这样处理后,就能保证每次page变化都能拿到最新的items来追加数据。同时注意组件卸载时要清理事件监听器和中断异步请求。
至于你担心的“页码重置”问题,可以在组件卸载时手动setPage(1),或者在初始化useEffect的时候加个标志位判断page是否为1,避免重复请求。
分页加载就是得把状态管理清楚,不能全靠依赖自动触发。
解决办法是把页码和数据分开管理,并且在初始化时单独处理第一页的数据。代码放这了:
这样写能保证第一次加载时不会重复追加,后续分页正常追加数据。如果你还遇到问题,可能是API返回的数据格式不对,记得检查一下res.data是不是数组。