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

React中AbortController无法终止GET请求且useEffect多次执行问题求助

Hey there! Let's break down what's happening with your code and fix that AbortController issue step by step.

First, let's clarify the core problem: in React 18's Strict Mode, your useEffect runs twice (mount → unmount → remount) to help you catch improper cleanup. When you moved your fetch logic into fetchData, the abort wasn't working as expected, and you saw more than two executions. Here's why, and how to fix it:

Key Issues & Fixes

1. Make Sure Your Axios Wrapper Properly Handles the Signal

The most common reason AbortController fails after encapsulation is that your get function from AxiosUtilities isn't passing the signal config to the underlying axios request. Double-check that your wrapper looks like this:

// components/AxiosUtilities.js
import axios from 'axios';

export const get = (url, config = {}) => {
  // Ensure we pass the full config (including signal) to axios.get
  return axios.get(url, config);
};

If your wrapper was ignoring the config parameter, the signal never reaches the request, so aborting does nothing.

2. Update Your Component Code to Handle Abort Errors & Cleanup

Your current code misses error handling for aborted requests, which can lead to confusing console warnings. Plus, we can simplify the logic to ensure proper cleanup:

import { get } from "components/AxiosUtilities";
import { visitations_url } from "components/Urls";
import React, { useEffect, useCallback } from "react";
import Layout from "components/Layout"; // Don't forget to import Layout!

const Visitations = () => {
  const fetchData = useCallback(async (controller) => {
    try {
      const res = await get(visitations_url, { signal: controller.signal });
      console.log("visitations", res.data);
      // Add your state update here, e.g., setVisitations(res.data)
    } catch (err) {
      // Ignore the AbortError to avoid unnecessary console warnings
      if (err.name !== "AbortError") {
        console.error("Failed to load visitations:", err);
      }
    }
  }, []);

  useEffect(() => {
    const controller = new AbortController();
    fetchData(controller);

    // Cleanup: abort the request when the component unmounts or re-renders
    return () => {
      controller.abort();
      console.log("Aborted pending visitations request");
    };
  }, [fetchData]);

  return (
    <Layout>
      <div className="w-full">
        {/* Render your data here once fetched */}
      </div>
    </Layout>
  );
};

export default Visitations;

Why This Works

  • AbortError Handling: When React unmounts the component (during Strict Mode's double-render), the cleanup function aborts the first request. We catch this specific error to avoid cluttering your console.
  • Stable fetchData: useCallback with an empty dependency array ensures fetchData doesn't change between renders, so useEffect only runs when it needs to (not on every re-render).
  • Proper Signal Passing: By ensuring your axios wrapper forwards the signal config, the AbortController can actually terminate the in-flight request.

About the "More Than Two Executions"

If you're seeing useEffect run more than twice, check for these:

  • Are there any state updates inside the component that trigger re-renders? For example, if you add a state setter inside fetchData, that will cause the component to re-render, which re-runs useEffect (but only if fetchData changes, which it shouldn't with useCallback).
  • Is the Layout component causing re-renders? If Layout has state changes, it could trigger re-renders of your Visitations component.

内容的提问来源于stack exchange,提问作者Ayush Chittranshi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 17:24:08