Introduction
If you've ever encountered a TypeError: Network request failed error when trying to connect your React Native app to a local development server, you're not alone. This is one of the most common issues developers face when building React Native applications. The error seems straightforward, but the root cause is often misunderstood.
In this article, we'll explore why localhost doesn't work in React Native, how to fix it, and best practices for handling API URLs across different platforms and environments.
The Problem
You've set up your backend server running on http://localhost:4000, and your React Native app is trying to fetch data from it. Everything looks correct, but you're getting this error:
ERROR Error fetching houses from server: [TypeError: Network request failed]
Your code might look something like this:
const API_URL = 'http://localhost:4000/api/open-homes';
const response = await fetch(API_URL);
This works perfectly in web browsers, but fails in React Native. Why?
Why localhost Fails in React Native
The fundamental issue is that localhost in React Native refers to the device or emulator itself, not your development machine.
Here's what happens on different platforms:
-
iOS Simulator:
localhostpoints to the simulator, not your Mac -
Android Emulator:
localhostpoints to the emulator, not your computer -
Physical Devices:
localhostpoints to the device itself, which doesn't have your server running
Unlike web browsers that run on your computer and can access localhost directly, React Native apps run in isolated environments (simulators, emulators, or physical devices) that don't have direct access to your development machine's localhost.
The Solution: Platform-Aware API Configuration
The solution is to create a platform-aware API URL configuration that uses the correct address for each platform. Here's how to implement it:
Step 1: Create a Configuration File
Create or update your environment configuration file (config/env.ts):
// config/env.ts
import { Platform } from 'react-native';
// Development vs Production configuration
export const isDevelopment = __DEV__;
// Get API base URL based on platform
// - iOS Simulator: localhost works
// - Android Emulator: use 10.0.2.2 (special IP that maps to host machine)
// - Physical devices: use your computer's local IP address (e.g., 192.168.x.x)
export const getApiBaseUrl = (): string => {
if (isDevelopment) {
// For Android emulator, use 10.0.2.2 instead of localhost
if (Platform.OS === 'android') {
return 'http://10.0.2.2:4000';
}
// For iOS simulator, localhost works
return 'http://localhost:4000';
}
// Production URL - update this with your production API URL
return 'https://your-production-api.com';
};
Step 2: Update Your API Calls
Update your context or service files to use the platform-aware URL:
// contexts/HousesContext.tsx
import { getApiBaseUrl } from '@/config/env';
const API_URL = `${getApiBaseUrl()}/api/open-homes`;
const loadHouses = async () => {
try {
const response = await fetch(API_URL);
if (!response.ok) {
throw new Error(`Failed to fetch houses: ${response.status}`);
}
const data = await response.json();
// Handle your data...
} catch (error) {
console.error('Error fetching houses from server:', error);
}
};
Platform-Specific Details
iOS Simulator
The iOS Simulator can access localhost directly because it runs on your Mac and shares the same network stack. So http://localhost:4000 works as expected.
if (Platform.OS === 'ios') {
return 'http://localhost:4000';
}
Android Emulator
The Android Emulator runs in a virtual machine with its own network interface. To access your host machine, you need to use the special IP address 10.0.2.2, which the Android emulator maps to your computer's localhost.
if (Platform.OS === 'android') {
return 'http://10.0.2.2:4000';
}
Physical Devices
When testing on a physical device (iPhone or Android phone), you need to use your computer's actual IP address on your local network. You can find this by:
On Mac/Linux:
ifconfig | grep "inet " | grep -v 127.0.0.1
On Windows:
ipconfig
Look for your local network IP (usually something like 192.168.1.x or 192.168.0.x).
Then update your configuration:
// For physical devices, use your computer's local IP
const LOCAL_IP = '192.168.1.141'; // Replace with your actual IP
if (Platform.OS === 'android') {
return `http://${LOCAL_IP}:4000`;
}
Important: Make sure your device and computer are on the same Wi-Fi network, and that your firewall allows connections on port 4000.
Common Pitfalls
Forgetting to Update IP for Physical Devices: If you switch networks or your IP changes, update your configuration.
Firewall Blocking Connections: Make sure your firewall allows incoming connections on your development port.
Different Networks: Ensure your device and computer are on the same Wi-Fi network when testing on physical devices.
HTTPS in Development: Some APIs require HTTPS. For local development, you might need to use
http://explicitly or set up SSL certificates.
Keywords: React Native, Network Request Failed, localhost, API Configuration, Mobile Development, iOS, Android, Development Tips
Top comments (1)
If this helped you, I’m writing more practical React Native troubleshooting guides. Follow me here or ask questions — happy to help others avoid the pain points I experienced.