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

React分页场景下useEffect重复触发请求问题求助

解决方案

1. 合并逻辑+请求防抖,避免重复触发

问题核心是过滤器变化时,第一个useEffect重置page会触发第二个useEffect二次执行,加上异步状态更新的滞后性,导致重复请求。用useRef跟踪请求状态,合并重置与请求逻辑即可解决:

import { useEffect, useRef, useState } from 'react';

// ... 你的其他状态定义(selectedDate、selectedCategory等)
const isFetching = useRef(false);

useEffect(() => {
  // 过滤器变化时,同步重置分页状态
  if (selectedDate || selectedCategory || selectedProvince) {
    setPage(1);
    setFilteredEvents([]);
  }

  // 封装请求逻辑,防止并发请求
  const fetchData = async () => {
    // 正在请求中/分页超出范围,直接返回
    if (isFetching.current || page > 4) return;

    isFetching.current = true;
    try {
      await fetchDataFromMain();
      // 请求完成后更新是否还有更多页(固定4页的场景)
      setHasMorePage(page < 4);
    } catch (err) {
      console.error('请求失败:', err);
    } finally {
      isFetching.current = false;
    }
  };

  fetchData();
}, [page, selectedDate, selectedCategory, selectedProvince, fetchDataFromMain]);

2. 移除冗余的hasMorePage状态(可选)

因为分页总数固定为4,完全可以直接用page <= 4判断是否继续请求,无需维护hasMorePage状态,减少状态同步问题:

const isFetching = useRef(false);

useEffect(() => {
  if (selectedDate || selectedCategory || selectedProvince) {
    setPage(1);
    setFilteredEvents([]);
  }

  const fetchData = async () => {
    if (isFetching.current || page > 4) return;

    isFetching.current = true;
    try {
      await fetchDataFromMain();
    } catch (err) {
      console.error('请求失败:', err);
    } finally {
      isFetching.current = false;
    }
  };

  fetchData();
}, [page, selectedDate, selectedCategory, selectedProvince, fetchDataFromMain]);

3. 缓存请求函数(如果fetchDataFromMain是组件内定义)

如果fetchDataFromMain是组件内部声明的函数,每次渲染都会重新创建,会导致useEffect频繁触发,用useCallback缓存它:

const fetchDataFromMain = useCallback(async () => {
  // 你的请求逻辑示例
  const response = await fetch(
    `/api/events?page=${page}&date=${selectedDate}&category=${selectedCategory}&province=${selectedProvince}`
  );
  const newData = await response.json();
  setFilteredEvents(prev => [...prev, ...newData]);
}, [page, selectedDate, selectedCategory, selectedProvince]);

核心优化点

  • 用useRef的isFetching标记请求状态,彻底避免并发/重复请求
  • 合并过滤器重置与请求逻辑,消除page重置导致的二次触发
  • 固定分页场景下,直接用page判断替代冗余状态,简化逻辑

内容的提问来源于stack exchange,提问作者Kadir Üretir

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 19:12:43