当前位置:首页 > React

react如何实现发起请求前取消上一个请求

2026-01-26 10:28:48React

使用 AbortController

在 React 中,可以通过 AbortController 取消正在进行的请求。AbortController 是现代浏览器提供的 API,用于中断请求。

创建一个 AbortController 实例,并将其 signal 属性传递给 fetch 请求。当需要取消请求时,调用 abort() 方法。

react如何实现发起请求前取消上一个请求

const controller = new AbortController();
fetch(url, { signal: controller.signal })
  .then(response => response.json())
  .catch(err => {
    if (err.name === 'AbortError') {
      console.log('Request was aborted');
    }
  });

// 取消请求
controller.abort();

结合 useEffect 清理函数

在 React 组件中,通常在 useEffect 中发起请求。利用 useEffect 的清理函数,可以在组件卸载或依赖项变化时取消未完成的请求。

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

  const fetchData = async () => {
    try {
      const response = await fetch(url, { signal: controller.signal });
      const data = await response.json();
      setData(data);
    } catch (err) {
      if (err.name !== 'AbortError') {
        console.error('Fetch error:', err);
      }
    }
  };

  fetchData();

  return () => {
    controller.abort();
  };
}, [url]);

封装自定义 Hook

可以将取消请求的逻辑封装为自定义 Hook,便于复用。

react如何实现发起请求前取消上一个请求

function useFetch(url) {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);

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

    const fetchData = async () => {
      try {
        const response = await fetch(url, { signal: controller.signal });
        const result = await response.json();
        setData(result);
      } catch (err) {
        if (err.name !== 'AbortError') {
          setError(err);
        }
      }
    };

    fetchData();

    return () => {
      controller.abort();
    };
  }, [url]);

  return { data, error };
}

结合 Axios 取消请求

如果使用 Axios,可以通过 CancelToken 实现类似功能。Axios 提供了更简洁的取消请求方式。

useEffect(() => {
  const source = axios.CancelToken.source();

  const fetchData = async () => {
    try {
      const response = await axios.get(url, {
        cancelToken: source.token
      });
      setData(response.data);
    } catch (err) {
      if (!axios.isCancel(err)) {
        console.error('Axios error:', err);
      }
    }
  };

  fetchData();

  return () => {
    source.cancel('Operation canceled by the user.');
  };
}, [url]);

处理多个请求的场景

当需要处理多个请求时,可以为每个请求分配独立的 AbortControllerCancelToken,确保取消操作只影响目标请求。

useEffect(() => {
  const controllers = {};

  const fetchData = async (url, key) => {
    controllers[key] = new AbortController();

    try {
      const response = await fetch(url, { signal: controllers[key].signal });
      const data = await response.json();
      setData(prev => ({ ...prev, [key]: data }));
    } catch (err) {
      if (err.name !== 'AbortError') {
        console.error(`Fetch error for ${key}:`, err);
      }
    }
  };

  fetchData('/api/data1', 'data1');
  fetchData('/api/data2', 'data2');

  return () => {
    Object.values(controllers).forEach(controller => controller.abort());
  };
}, []);

通过以上方法,可以在 React 应用中灵活地取消未完成的请求,避免潜在的内存泄漏或竞态条件问题。

分享给朋友:

相关文章

react 如何引入css

react 如何引入css

在 React 中引入 CSS 的方法 React 提供了多种引入 CSS 的方式,可以根据项目需求选择合适的方法。以下是常见的几种方式: 内联样式 内联样式直接在组件中通过 style 属性定义,…

vue如何实现登录

vue如何实现登录

实现登录功能的基本步骤 使用Vue实现登录功能通常需要结合后端API、状态管理以及路由控制。以下是常见的实现方式: 创建登录表单组件 在Vue组件中构建包含用户名和密码输入框的表单: <te…

vue中如何实现循环

vue中如何实现循环

循环渲染列表数据 在Vue中,使用v-for指令实现循环渲染。基本语法为v-for="(item, index) in items",其中items是数据源数组,item是当前遍历的元素,index是…

如何生成react代码

如何生成react代码

使用 Create React App 生成项目 安装 Node.js 后,通过命令行工具运行以下命令创建新项目: npx create-react-app my-app cd my-app npm…

如何配置react

如何配置react

配置React项目的步骤 安装Node.js和npm 确保系统已安装Node.js(包含npm)。可通过官网下载并安装最新版本。安装完成后,运行以下命令验证版本: node -v npm -v 创建…

vue如何实现tap

vue如何实现tap

Vue 中实现类似移动端 tap 事件的方法 在 Vue 中可以通过以下几种方式实现类似移动端 tap(轻触)事件的效果: 使用第三方库 安装 v-tap 指令库可以快速实现 tap 事件: np…