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

React中调用axios.get时useEffect执行异常排查求助

React组件useEffect执行异常排查与修复

问题背景

开发的ClientMainPage组件包含两个useEffect钩子:一个用于从后端获取裁缝列表,另一个根据选中项排序数据。但运行时出现不稳定情况:有时两个useEffect均不执行,有时能正常获取数据。

核心问题分析

  1. JSX中非法调用状态更新函数
    组件返回的else分支中直接调用setIsfetch(false),每次渲染到该分支都会触发状态更新,导致组件无限重渲染。React会限制这种异常重渲染行为,进而干扰useEffect的正常执行。

  2. 加载状态管理混乱
    第一个useEffect一开始就设置isfetch=true,此时数据尚未加载完成;同时未在请求完成(成功/失败)时更新状态,导致UI展示逻辑与数据状态脱节。

  3. 排序逻辑依赖缺失
    排序useEffect仅依赖sortItemSelected,当数据加载完成后,无法自动应用当前选中的排序规则;且直接使用当前dataTailors状态进行排序,可能因状态更新时机问题导致排序结果异常。

  4. 错误处理不严谨
    uFetch类中请求失败时仅打印错误但返回undefined,会导致setDataTailors将状态设置为undefined,引发后续组件渲染错误。

修复方案与代码示例

修复后的ClientMainPage组件

export const ClientMainPage = () => {
  const [dataTailors, setDataTailors] = useState([]);
  const [sortItemSelected, setSortItemSelected] = useState("none");  
  const [isFetching, setIsFetching] = useState(true); // 初始标记为正在加载

  // 数据获取逻辑
  useEffect(() => {
    const fetchTailors = async () => {
      try {
        const uFetchAux = new uFetch();
        const tailors = await uFetchAux.getAllTailors();
        setDataTailors(tailors || []); // 兜底处理空数据
      } catch (error) {
        console.error("获取裁缝列表失败:", error);
        setDataTailors([]);
      } finally {
        setIsFetching(false); // 请求结束后统一更新加载状态
      }
    };

    fetchTailors();
  }, []);

  // 排序逻辑:使用函数式更新避免状态依赖问题
  useEffect(() => {
    setDataTailors(prevTailors => {
      const sorted = [...prevTailors];
      switch(sortItemSelected) {
        case "asc":
          return sorted.sort((a, b) => a.name.localeCompare(b.name));
        case "desc":
          return sorted.sort((a, b) => b.name.localeCompare(a.name));
        default:
          return [...prevTailors];
      }
    });
  }, [sortItemSelected]);


  return (
    <div className="MainPage">
      {isFetching ? (
        <div>加载中...</div> {/* 替换为自定义加载组件 */}
      ) : (
        <div>
          <NavBar title="Cliente">
            <SortBy sortItems={(items) => setSortItemSelected(items)} />
          </NavBar>        
          <ClientTable tailors={dataTailors} />
        </div>
      )}
    </div>
  );
};

优化后的uFetch类

import axios from "axios";

class uFetch {
  async getAllTailors() {
    const http = axios.create({
      baseURL: "http://localhost:8088",
      headers: {
        "Content-type": "application/json"
      },
      responseType: "json",
      mode: "cors",
    });
    try {
      const resp = await http.get("/tailor");
      console.log(resp.data);
      return resp.data;
    } catch (error) {
      console.error("请求裁缝列表接口失败:", error);
      throw error; // 抛出错误让上层组件处理
    }
  }
}
export default uFetch;

关键修复点总结

  • 移除JSX中直接调用setIsfetch(false)的代码,改用初始加载状态+请求结束后更新的方式,避免无限重渲染。
  • 数据获取使用async/await语法,统一在finally块中更新加载状态,确保UI状态与数据状态一致。
  • 排序逻辑使用函数式更新setDataTailors(prev => ...),避免依赖当前状态引发的逻辑错误,同时防止循环更新。
  • 优化错误处理,uFetch类抛出错误让组件捕获处理,避免状态被设置为undefined。

内容的提问来源于stack exchange,提问作者javier Piña

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 08:00:32