Skip to content

React Native - HTTP 请求

本章演示如何在 React Native 中使用 HTTP 请求从远程服务器获取数据。我们将使用内置的 fetch API,它是在 JavaScript 环境中发起网络请求的现代标准。

结合 fetch、async/await 和 Hooks 使用

Section titled “结合 fetch、async/await 和 Hooks 使用”

我们将创建一个组件,该组件在挂载时从公共 API(jsonplaceholder.typicode.com)获取一组帖子数据,并显示第一篇帖子的标题。我们将使用 useEffect 触发数据获取,并使用 useState 存储获取到的数据以及加载/错误状态。

DataFetcher.js

import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, ActivityIndicator, Button } from 'react-native';
const DataFetcher = () => {
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const fetchData = async () => {
setLoading(true);
setError(null);
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const jsonResponse = await response.json();
setData(jsonResponse);
} catch (e) {
console.error("Fetch error: ", e);
setError(e.message);
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchData(); // 组件挂载时获取数据
// 可选:如果需要可添加清理函数(例如,取消 fetch 请求)
// return () => {
// // 清理逻辑
// };
}, []); // 空依赖数组意味着此 Effect 只在挂载时运行一次
if (loading) {
return (
<View style={styles.container}>
<ActivityIndicator size="large" color="#0000ff" />
<Text>Loading data...</Text>
</View>
);
}
if (error) {
return (
<View style={styles.container}>
<Text style={styles.errorText}>Error fetching data: {error}</Text>
<Button title="Retry" onPress={fetchData} />
</View>
);
}
return (
<View style={styles.container}>
{data ? (
<View>
<Text style={styles.title}>Fetched Post Title:</Text>
<Text style={styles.bodyText}>{data.title}</Text>
<Text style={styles.title}>Post Body:</Text>
<Text style={styles.bodyText}>{data.body}</Text>
</View>
) : (
<Text>No data fetched.</Text>
)}
<Button title="Fetch Again" onPress={fetchData} />
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
},
title: {
fontSize: 18,
fontWeight: 'bold',
marginTop: 10,
},
bodyText: {
fontSize: 16,
marginVertical: 5,
textAlign: 'center',
},
errorText: {
color: 'red',
fontSize: 16,
marginBottom: 10,
}
});
export default DataFetcher;
  • State 变量:data 存储获取到的响应数据,loading 表示请求是否正在进行中,error 存储任何错误消息。
  • useEffect Hook:fetchData 函数在 useEffect 中调用。空的依赖数组 [] 确保此 effect 仅在初始渲染后运行一次(类似于类组件中的 componentDidMount)。
  • async/await:简化异步代码,使其看起来更像同步代码。await fetch(...) 会暂停执行,直到 Promise 解决(resolve)。
  • 错误处理:我们使用 try...catch 块来处理潜在的网络错误或响应问题(例如,response.ok 检查 HTTP 状态码,如 404 或 500)。
  • 加载和错误 UI:组件根据 loading 和 error 状态渲染不同的 UI,提供更好的用户反馈。
  • response.json():Response 对象上的此方法将响应主体解析为 JSON。

当此组件渲染时,它将显示一个加载指示器,然后从 URL 获取数据。如果成功,则显示获取到的帖子的标题和正文。如果发生错误,将显示错误消息并带有一个重试按钮。

发起其他类型的请求(POST, PUT, DELETE)

Section titled “发起其他类型的请求(POST, PUT, DELETE)”

fetch API 也可用于其他 HTTP 方法,如 POST、PUT、DELETE。您需要为 fetch 提供第二个参数,其中包含一个配置对象:

const postData = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST', // 指定请求方法
headers: {
'Content-Type': 'application/json', // 指定内容类型
// 'Authorization': 'Bearer YOUR_TOKEN_HERE', // 认证示例
},
body: JSON.stringify({ // 将 JavaScript 对象转换为 JSON 字符串
title: 'foo',
body: 'bar',
userId: 1,
}),
});
const jsonResponse = await response.json();
console.log('POST Response:', jsonResponse);
} catch (error) {
console.error('Error posting data:', error);
}
};

对于更复杂的场景,或者如果您喜欢功能更丰富的库(如自动请求/响应转换、拦截器),可以考虑使用 Axios 等库。然而,fetch 对于许多用例来说功能强大且足够。

延伸阅读:MDN Fetch API documentation