React.js:如何实现滚动到屏幕底部时仅调用一次函数?
解决滚动加载重复调用的问题
要避免滚动到底部时loadProgramList被多次调用,核心是添加加载状态锁,确保同一时间只有一个请求在执行。具体实现步骤如下:
1. 新增加载状态变量
用useState创建布尔状态,标记当前是否处于数据加载中:
const [isLoading, setIsLoading] = useState(false);
2. 修改loadProgramList函数
在函数开头判断加载状态,若正在加载则直接返回;请求开始时锁定状态,请求结束(无论成功/失败)后解锁:
const loadProgramList = () => { // 正在加载时直接返回,阻止重复调用 if (isLoading) return; setIsLoading(true); // 开启加载锁 refreshToken() .then((refresh) => { return fetch("http://localhost:5000/program/load-program-list", { method: "POST", headers: { "Content-type": "application/json", Authorization: `Bearer ${Cookies.get("accessToken")}`, }, body: JSON.stringify({ index: index }), }); }) .then((response) => { if (!response.ok) { return response.json().then((data) => { throw { error: data.error, status: response.status }; }); } return response.json(); }) .then((data) => { if (data.success) { setPrograms((prevPrograms) => prevPrograms.concat(data.programs)); setIndex((prevIndex) => prevIndex + 10); } }) .catch((error) => { if (error.status === 401) { Cookies.remove("accessToken"); Cookies.remove("refreshToken"); window.location.reload(); ctx.setLoginModal(true); ctx.setStatus("Session timed out: You have been logged out"); } else { navigate("/error", { state: { error: error.error, status: error.status }, }); } }) .finally(() => { // 请求完成后解锁加载状态 setIsLoading(false); }); };
3. 更新滚动监听逻辑
在handleScroll中,除了判断滚动位置,还要检查加载状态,仅当未加载时才触发请求:
useEffect(() => { loadProgramList(); const handleScroll = () => { // 滚动到底部 + 未处于加载状态,才执行加载 if (window.innerHeight + window.scrollY >= document.body.offsetHeight && !isLoading) { loadProgramList(); } }; window.addEventListener("scroll", handleScroll); return () => { window.removeEventListener("scroll", handleScroll); }; }, [index, isLoading]); // 依赖项添加isLoading
额外修正说明
原代码catch块中error.response === 401存在错误,已修正为error.status === 401,匹配抛出的错误对象结构。
内容的提问来源于stack exchange,提问作者Jia Huang
相关产品推荐
相关产品推荐

