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

React Native中点击按钮后导航离开时如何使用AbortController?

用AbortController中止React Native中的Axios请求

完全可以用AbortController解决这个问题,而且实现起来很直接,刚好能匹配你说的场景——用户导航离开页面时,自动中止未完成的接口请求,避免无效请求占用资源。

下面是具体的实现步骤和代码示例:

核心思路

  1. 用useRef保存AbortController实例,确保它在组件的整个生命周期内保持引用,不会随渲染重置。
  2. 发起Axios请求时,把控制器的signal属性传入请求配置,让请求和控制器关联。
  3. 在组件卸载(或页面失焦)时,调用控制器的abort()方法,中止关联的请求。

代码示例:普通组件卸载场景

如果你的页面在导航离开时会被卸载,直接用useEffect的清理函数即可:

import { useEffect, useRef, useState } from 'react';
import axios from 'axios';
import { Button, Modal, Text, View } from 'react-native';

const DataModalPage = () => {
  const [modalVisible, setModalVisible] = useState(false);
  const [fetchData, setFetchData] = useState(null);
  // 保存AbortController实例
  const abortControllerRef = useRef(new AbortController());

  const handleFetchAndOpenModal = async () => {
    try {
      // 发起请求时关联signal
      const response = await axios.get('你的接口地址', {
        signal: abortControllerRef.current.signal
      });
      setFetchData(response.data);
      setModalVisible(true);
    } catch (error) {
      // 捕获请求中止的错误,避免控制台报错
      if (axios.isCancel(error)) {
        console.log('接口请求已被中止');
      } else {
        console.error('请求失败:', error);
      }
    }
  };

  // 组件卸载时中止请求
  useEffect(() => {
    return () => {
      abortControllerRef.current.abort();
    };
  }, []);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Button title="打开弹窗并加载数据" onPress={handleFetchAndOpenModal} />
      <Modal
        visible={modalVisible}
        onRequestClose={() => setModalVisible(false)}
        animationType="slide"
      >
        <View style={{ flex: 1, padding: 20 }}>
          <Text>{fetchData ? JSON.stringify(fetchData) : '加载中...'}</Text>
        </View>
      </Modal>
    </View>
  );
};

export default DataModalPage;

补充:React Navigation页面失焦场景

如果用React Navigation,页面切换时组件可能不会立即卸载(比如栈导航的保留页面),这时可以用useFocusEffect监听页面失焦事件,在失焦时中止请求:

import { useFocusEffect } from '@react-navigation/native';
import { useRef, useState } from 'react';
import axios from 'axios';
import { Button, Modal, Text, View } from 'react-native';

const DataModalPage = () => {
  const [modalVisible, setModalVisible] = useState(false);
  const [fetchData, setFetchData] = useState(null);
  const abortControllerRef = useRef(new AbortController());

  const handleFetchAndOpenModal = async () => {
    try {
      const response = await axios.get('你的接口地址', {
        signal: abortControllerRef.current.signal
      });
      setFetchData(response.data);
      setModalVisible(true);
    } catch (error) {
      if (axios.isCancel(error)) {
        console.log('接口请求已被中止');
      } else {
        console.error('请求失败:', error);
      }
    }
  };

  // 页面获得焦点时重置控制器,避免旧信号影响新请求
  // 页面失焦时中止请求
  useFocusEffect(
    () => {
      abortControllerRef.current = new AbortController();
      return () => {
        abortControllerRef.current.abort();
      };
    },
    []
  );

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Button title="打开弹窗并加载数据" onPress={handleFetchAndOpenModal} />
      <Modal
        visible={modalVisible}
        onRequestClose={() => setModalVisible(false)}
        animationType="slide"
      >
        <View style={{ flex: 1, padding: 20 }}>
          <Text>{fetchData ? JSON.stringify(fetchData) : '加载中...'}</Text>
        </View>
      </Modal>
    </View>
  );
};

export default DataModalPage;

注意事项

  • 每次发起新请求前,最好重置AbortController实例(比如用户多次点击按钮时),避免之前的中止信号影响新请求。
  • 一定要捕获axios.isCancel(error)的错误,不然控制台会抛出未处理的异常。
  • AbortController是标准API,Axios原生支持,React Native环境下可以直接使用,不需要额外配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 01:57:18