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:useCallbackwith an empty dependency array ensuresfetchDatadoesn't change between renders, souseEffectonly runs when it needs to (not on every re-render). - Proper Signal Passing: By ensuring your axios wrapper forwards the
signalconfig, 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-runsuseEffect(but only iffetchDatachanges, which it shouldn't withuseCallback). - Is the
Layoutcomponent causing re-renders? IfLayouthas state changes, it could trigger re-renders of yourVisitationscomponent.
内容的提问来源于stack exchange,提问作者Ayush Chittranshi

