React Native Android切换网络后Fetch API请求失败排查求助
Problem Description
I've built a React Native Android app that lets users log in and view information. Everything works fine initially—users can log in, view content, and log out multiple times without issues. But after switching between WiFi and mobile data, any attempt to log in or fetch data throws this error:
Network request failed at XMLHttpRequest.xhr.onerror (fetch.js:441)
I'm using the Fetch API for network calls. Here's my request implementation:
export const request = async function request(path, body = null, method = 'GET') { try { const headers = { 'Content-Type': body instanceof FormData ? 'multipart/form-data' : 'application/json', }; const token = await AsyncStorage.getItem('authToken'); if (token) { headers.Authorization = token; } const config = { method, url: Config.API_URL + path, headers, }; if (!['HEAD', 'GET'].includes(method.toUpperCase())) { config.body = body instanceof FormData ? body : JSON.stringify(body); } const response = await fetch(Config.API_URL + path, config); const data = await response.json(); if (response.status >= 400) { throw data.error; } return data; } catch (e) { console.log('Error', path, e); return Promise.reject(e); } };
Full error stack trace:
Network request failed at XMLHttpRequest.xhr.onerror (fetch.js:441) at XMLHttpRequest.dispatchEvent (event-target.js:172) at XMLHttpRequest.setReadyState (XMLHttpRequest.js:567) at XMLHttpRequest.__didCompleteResponse (XMLHttpRequest.js:397) at XMLHttpRequest.js:503 at RCTDeviceEventEmitter.emit (EventEmitter.js:179) at MessageQueue.__callFunction (MessageQueue.js:351) at MessageQueue.js:116 at MessageQueue.__guardSafe (MessageQueue.js:314)
My Android SDK versions:
- compileSdkVersion: 25
- buildToolsVersion: "25.0.2"
- minSdkVersion: 16
- targetSdkVersion: 25
I'm new to React Native and can't pinpoint the issue. Any help would be greatly appreciated!
Answer
Hey there! This is a super common gotcha with React Native's Fetch API on older Android versions—let's break down some fixes you can try right away:
1. Add a Network State Listener to Reset Requests
Android doesn't always notify React Native immediately when the network switches, which can leave the underlying HTTP client in a broken state. Use the @react-native-community/netinfo package to listen for network changes and reset your request logic:
First, install the package:
npm install @react-native-community/netinfo
Then add a listener in your app setup:
import NetInfo from '@react-native-community/netinfo'; // Add this in your root component or service initialization NetInfo.addEventListener(state => { if (state.isConnected) { // When network reconnects, clear pending requests or retry failed ones console.log('Network reconnected—resetting request state'); // You could also add logic here to retry the last failed fetch call } });
2. Disable HTTP Keep-Alive (Quick Test)
Older Android versions struggle with persistent HTTP connections after network switches. Force a fresh connection for each request by adding a header:
const headers = { 'Content-Type': body instanceof FormData ? 'multipart/form-data' : 'application/json', 'Connection': 'close' // Add this line to disable keep-alive };
This is a temporary fix but will help confirm if keep-alive is the culprit.
3. Check Network Security Config (If Using HTTP)
If your API uses HTTP (not HTTPS), Android 7+ blocks cleartext traffic by default. Switching networks might trigger this restriction. Create a res/xml/network_security_config.xml file:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <base-config cleartextTrafficPermitted="true"> <trust-anchors> <certificates src="system" /> </trust-anchors> </base-config> </network-security-config>
Then reference it in your AndroidManifest.xml:
<application ... android:networkSecurityConfig="@xml/network_security_config">
4. Try Axios Instead of Fetch
Many developers find Axios handles network switches more reliably than the native Fetch API. Here's how to refactor your request function:
Install Axios:
npm install axios
Updated request function:
import axios from 'axios'; import AsyncStorage from '@react-native-async-storage/async-storage'; export const request = async function request(path, body = null, method = 'GET') { try { const headers = { 'Content-Type': body instanceof FormData ? 'multipart/form-data' : 'application/json', }; const token = await AsyncStorage.getItem('authToken'); if (token) { headers.Authorization = token; } const config = { method, url: Config.API_URL + path, headers, data: body, }; const response = await axios(config); return response.data; } catch (e) { console.log('Error', path, e); return Promise.reject(e.response?.data?.error || e.message); } };
5. Update Dependencies (Long-Term Fix)
Your Android SDK versions are quite outdated (compileSdk 25 is Android 7.1). React Native has fixed dozens of network-related bugs in newer versions—if possible, upgrade to a stable RN version (0.60+) and update your build tools to at least 28.0.3.
Start with fixes 1 and 2 since they're the fastest to test. Let me know if any of these work for you!
内容的提问来源于stack exchange,提问作者Mukund Kumar

