React Native使用fetch获取API数据失败求助
Hey there, let's work through this network issue together! I've looked over your code and problem details, and here are the most common fixes to get your React Native app talking to your local JSON-server API:
1. Fix Local API URL Resolution
The way you're resolving the API URL using Constants.manifest can be unreliable across different devices/emulators. Here's why:
- Android emulators map
localhostto the emulator itself, not your computer. You need to use10.0.2.2to access your host machine's localhost. - iOS emulators can use
localhost, but using your computer's actual local network IP (like192.168.1.100) works better for both simulators and physical devices on the same network.
Update your URL logic to handle these cases:
import { Platform } from 'react-native'; const { manifest } = Constants; const getApiUrl = () => { if (manifest.packagerOpts.dev) { if (Platform.OS === 'android') { // Android emulator uses this to reach host machine return '10.0.2.2:3000'; } else { // Replace with your computer's local IP (find via `ifconfig`/`ipconfig`) return '192.168.1.100:3000'; } } return 'api.example.com'; }; const api = getApiUrl(); const url = `http://${api}/events`; export function getEvents() { return fetch(url) .then(response => { // Add HTTP status check to catch non-200 responses if (!response.ok) throw new Error(`Status: ${response.status}`); return response.json(); }) .then(events => events.map(e => ({ ...e, date: new Date(e.date) }))) .catch(err => { console.error('Fetch failed:', err); throw err; // Re-throw to let components handle the error }); }
2. Make JSON-server Accessible to Devices
By default, JSON-server only listens on 127.0.0.1 (localhost), which means only your computer's browser can reach it. To let emulators/phones connect, start the server with the --host 0.0.0.0 flag:
json-server --watch db.json --host 0.0.0.0
This makes the server listen on all your computer's network interfaces, so devices on the same LAN can connect.
3. Verify Platform Permissions
Android
Ensure your AndroidManifest.xml includes these network permissions (usually in android/app/src/main/):
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
iOS
iOS blocks non-HTTPS requests by default. For development, add this to your Info.plist (in ios/YourAppName/):
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>
(Note: For production, replace this with domain-specific exceptions instead of allowing all arbitrary loads.)
4. Debug with Device Browser
Before blaming React Native, test the API directly on your device:
- On a physical phone, open the browser and go to
http://[your-computer-ip]:3000/events - If it loads, the network is fine—focus on your React Native code
- If it doesn't, check your computer's firewall, router settings, or ensure JSON-server is running with
--host 0.0.0.0
5. Add Error Handling to Your Fetch
Your current fetch code doesn't handle errors, so you're missing critical debug info. The updated getEvents function above includes a catch block to log errors to the console—this will tell you exactly what's going wrong (e.g., DNS failure, connection timeout, or HTTP error).
内容的提问来源于stack exchange,提问作者Ahmed yar Tanveer

