You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 12:41:24