React调用API实现加载更多仅生效一次的问题排查
加载更多功能仅首次生效的问题排查与解决
问题描述
实现网站加载更多功能时,点击按钮调用函数为count增加5,再根据count值请求API,但按钮仅第一次能成功加载更多数据,控制台打印的count值出现重复。
问题原因
代码中的count是普通变量,而非React状态变量。当调用setBeerList更新组件状态时,组件会重新渲染,此时let count = 10会再次执行,将count重置为初始值10。第一次点击按钮时count变为15,请求到15条数据;组件重新渲染后count回到10,后续点击按钮时count又变为15,导致每次请求的per_page参数都是15,无法真正实现累加加载。
修复方案
将count改为React状态变量,确保组件重新渲染时能保留最新的count值:
import React, { useEffect, useState } from "react"; import "./BeerList.css"; const BeerList = () => { const [beerList, setBeerList] = useState(null); // 将count改为状态变量 const [count, setCount] = useState(10); const loadBeers = async () => { const response = await fetch( `https://api.punkapi.com/v2/beers?per_page=${count}` ); const results = await response.json(); const randomBeerList = results.map((beersObj) => ({ name: beersObj.name, tagline: beersObj.tagline, url: beersObj.image_url, })); setBeerList(randomBeerList); }; useEffect(() => { loadBeers(); }, []); const increment = () => { // 使用setCount更新状态,确保值被正确保留 setCount(prevCount => prevCount + 5); } // 监听count变化,自动触发新的加载请求 useEffect(() => { if (beerList !== null) { // 避免初始加载时重复触发 loadBeers(); } }, [count]); if (beerList === null) { return <div>Loading...</div>; } return ( <div className="beer-list-parent"> <div className="beer-list"> {beerList.map(({ name, tagline, url }, key) => ( <div key={key} className="beer"> <div className="beer-img"> <img src={url} className="url" /> </div> <div className="beer-text"> <div className="name">{name}</div> <div className="tagline">"{tagline}"</div> </div> </div> ))} </div> <div id="loadmore" className="more-parent"> <button className="more" type="button" onClick={increment}>Load more</button> </div> </div> ); }; export default BeerList;
额外优化建议
当前逻辑每次请求都会重新获取前count条数据,而非加载下一页的新数据,会造成重复请求和数据重复展示。可以结合API的分页参数实现真正的增量加载:
- 添加
page状态变量,初始值为1 - 点击加载更多时,
page加1 - 请求API时使用
page和固定的per_page=5参数 - 新请求的数据追加到现有列表中,而非替换
核心逻辑示例:
const [beerList, setBeerList] = useState([]); const [page, setPage] = useState(1); const perPage = 5; const loadBeers = async () => { const response = await fetch( `https://api.punkapi.com/v2/beers?page=${page}&per_page=${perPage}` ); const results = await response.json(); const newBeers = results.map((beersObj) => ({ name: beersObj.name, tagline: beersObj.tagline, url: beersObj.image_url, })); // 追加新数据到现有列表 setBeerList(prevList => [...prevList, ...newBeers]); }; useEffect(() => { loadBeers(); }, [page]); const increment = () => { setPage(prevPage => prevPage + 1); };
内容的提问来源于stack exchange,提问作者Marc López Soler
相关产品推荐
相关产品推荐

