DEV Community

Cathy Lai
Cathy Lai

Posted on

Fixing "Network Request Failed" in React Native: The localhost Problem

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]
Enter fullscreen mode Exit fullscreen mode

Your code might look something like this:

const API_URL = 'http://localhost:4000/api/open-homes';

const response = await fetch(API_URL);
Enter fullscreen mode Exit fullscreen mode

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: localhost points to the simulator, not your Mac
  • Android Emulator: localhost points to the emulator, not your computer
  • Physical Devices: localhost points 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';
};
Enter fullscreen mode Exit fullscreen mode

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);
    }
};
Enter fullscreen mode Exit fullscreen mode

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';
}
Enter fullscreen mode Exit fullscreen mode

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';
}
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

On Windows:

ipconfig
Enter fullscreen mode Exit fullscreen mode

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`;
}
Enter fullscreen mode Exit fullscreen mode

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

  1. Forgetting to Update IP for Physical Devices: If you switch networks or your IP changes, update your configuration.

  2. Firewall Blocking Connections: Make sure your firewall allows incoming connections on your development port.

  3. Different Networks: Ensure your device and computer are on the same Wi-Fi network when testing on physical devices.

  4. 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)

Collapse
 
cathylai profile image
Cathy Lai

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.