React Native 全栈开发实战班 - 网络与数据之网络请求基础

在移动应用中,网络请求 是实现与服务器进行数据交互的核心功能。React Native 基于 JavaScript 的特性,提供了多种方式进行网络请求,包括使用 fetch API、axios 库以及 WebSocket 等。本章节将详细介绍如何在 React Native 中进行网络请求,包括基本用法、错误处理、请求拦截以及使用第三方库进行更复杂的网络操作。


1.1 网络请求概述

在 React Native 应用中,网络请求主要用于以下场景:

  • 数据获取: 从服务器获取数据,如用户信息、文章列表等。
  • 数据提交: 向服务器提交数据,如用户注册、登录、发布文章等。
  • 实时通信: 通过 WebSocket 实现实时数据推送,如聊天应用、实时通知等。

React Native 提供了多种方式进行网络请求:

  1. fetch API: 内置于 JavaScript 的网络请求 API,简单易用。
  2. axios 库: 第三方网络请求库,功能更强大,支持拦截器、取消请求等。
  3. WebSocket: 用于实现实时双向通信。

本章节将重点介绍 fetch API 和 axios 库的使用。


1.2 使用 fetch API

fetch 是 JavaScript 提供的一个用于进行网络请求的 API,React Native 对其进行了支持。

1.2.1 基本用法

语法:

fetch(url, {method: 'GET', // 请求方法:GET, POST, PUT, DELETE, etc.headers: {'Content-Type': 'application/json',// 其他头部信息},body: JSON.stringify(data), // 请求体
}).then((response) => response.json()).then((json) => {// 处理响应数据}).catch((error) => {// 处理错误});

示例:GET 请求

import React, { useEffect, useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';const DataFetcher = () => {const [data, setData] = useState(null);useEffect(() => {fetch('https://jsonplaceholder.typicode.com/posts/1').then((response) => response.json()).then((json) => setData(json)).catch((error) => console.error(error));}, []);return (<View style={styles.container}>{data ? (<Text style={styles.text}>{JSON.stringify(data)}</Text>) : (<Text>Loading...</Text>)}</View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},text: {fontSize: 16,},
});export default DataFetcher;

示例:POST 请求

import React, { useState } from 'react';
import { View, Text, Button, StyleSheet } from 'react-native';const DataPoster = () => {const [response, setResponse] = useState(null);const postData = () => {const data = { title: 'foo', body: 'bar', userId: 1 };fetch('https://jsonplaceholder.typicode.com/posts', {method: 'POST',headers: {'Content-Type': 'application/json',},body: JSON.stringify(data),}).then((response) => response.json()).then((json) => setResponse(json)).catch((error) => console.error(error));};return (<View style={styles.container}><Button title="Post Data" onPress={postData} />{response && <Text style={styles.text}>{JSON.stringify(response)}</Text>}</View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},text: {fontSize: 16,marginTop: 10,},
});export default DataPoster;
1.2.2 错误处理

在网络请求中,错误处理是非常重要的。可以通过 catch 捕获错误,并进行相应的处理。

示例:

import React, { useEffect, useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';const ErrorHandlingExample = () => {const [error, setError] = useState(null);useEffect(() => {fetch('https://invalid-url.com/data').then((response) => response.json()).then((json) => {// 处理数据}).catch((error) => {console.error(error);setError('网络请求失败');});}, []);return (<View style={styles.container}>{error && <Text style={styles.text}>{error}</Text>}</View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},text: {fontSize: 16,color: 'red',},
});export default ErrorHandlingExample;
1.2.3 请求拦截

fetch 本身不支持请求拦截,但可以通过封装 fetch 函数来实现。

示例:

// api.js
import { Platform } from 'react-native';const api = {get: (url, headers = {}) => {return fetch(url, {method: 'GET',headers: {'Content-Type': 'application/json',...headers,},});},post: (url, data, headers = {}) => {return fetch(url, {method: 'POST',headers: {'Content-Type': 'application/json',...headers,},body: JSON.stringify(data),});},// 其他方法:put, delete, etc.
};// 添加请求拦截器
api.interceptors = {request: {use: (callback) => {const originalGet = api.get;api.get = (url, headers) => {return callback(originalGet(url, headers));};const originalPost = api.post;api.post = (url, data, headers) => {return callback(originalPost(url, data, headers));};// 其他方法},},
};export default api;
// App.js
import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import api from './api';api.interceptors.request.use((originalFetch) => (...args) => {// 添加请求头const [url, options] = args;options.headers = {...options.headers,Authorization: 'Bearer token',};return originalFetch(url, options);
});const App = () => {const fetchData = async () => {try {const response = await api.get('https://jsonplaceholder.typicode.com/posts/1');const json = await response.json();console.log(json);} catch (error) {console.error(error);}};return (<View style={styles.container}><Text style={styles.text}>Fetch Data</Text><Button title="Get Data" onPress={fetchData} /></View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',},text: {fontSize: 18,},
});export default App;

1.3 使用 axios

axios 是一个第三方网络请求库,功能更强大,支持拦截器、取消请求、请求超时等。相比 fetchaxios 提供了更简洁的 API 和更丰富的功能。

1.3.1 安装 axios
npm install axios
1.3.2 基本用法

以下是一个使用 axios 发送 POST 请求的示例:

// components/PostData.js
import React, { useState } from 'react';
import { View, Text, Button, StyleSheet, ActivityIndicator } from 'react-native';
import axios from 'axios';const PostData = () => {const [response, setResponse] = useState(null);const [loading, setLoading] = useState(false);const handlePost = async () => {setLoading(true);try {const data = { title: 'foo', body: 'bar', userId: 1 };const res = await axios.post('https://jsonplaceholder.typicode.com/posts', data);setResponse(res.data);} catch (error) {console.error(error);alert('请求失败');} finally {setLoading(false);}};return (<View style={styles.container}><Button title="Post Data" onPress={handlePost} />{loading && <ActivityIndicator size="large" color="#0000ff" />}{response && (<View style={styles.responseContainer}><Text style={styles.responseText}>Response:</Text><Text>{JSON.stringify(response)}</Text></View>)}</View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',padding: 20,},responseContainer: {marginTop: 20,padding: 10,backgroundColor: '#f0f0f0',borderRadius: 5,},responseText: {fontSize: 16,fontWeight: 'bold',marginBottom: 5,},
});export default PostData;

解释:

  • 发送 POST 请求:

    • 使用 axios.post 方法发送 POST 请求,第一个参数是请求的 URL,第二个参数是请求体数据。
    • axios.post 返回一个 Promise,可以通过 thencatch 处理响应和错误。
  • 错误处理:

    • 使用 try...catch 捕获请求错误,并进行相应处理(如显示错误提示)。
  • 加载状态:

    • 使用 loading 状态控制 ActivityIndicator 的显示,提示用户请求正在进行中。
  • 显示响应数据:

    • 将响应数据存储在 response 状态中,并在界面上显示。
1.3.3 拦截器

axios 提供了请求拦截器和响应拦截器,可以在请求发送前和响应返回后进行统一处理。

示例:添加请求头和响应处理

// api.js
import axios from 'axios';// 创建 axios 实例
const api = axios.create({baseURL: 'https://jsonplaceholder.typicode.com',
});// 添加请求拦截器
api.interceptors.request.use((config) => {// 在发送请求之前做些什么config.headers['Authorization'] = 'Bearer token';return config;},(error) => {// 对请求错误做些什么return Promise.reject(error);}
);// 添加响应拦截器
api.interceptors.response.use((response) => {// 对响应数据做点什么return response;},(error) => {// 对响应错误做点什么return Promise.reject(error);}
);export default api;
// components/PostData.js
import React, { useState } from 'react';
import { View, Text, Button, StyleSheet, ActivityIndicator } from 'react-native';
import api from '../api';const PostData = () => {const [response, setResponse] = useState(null);const [loading, setLoading] = useState(false);const handlePost = async () => {setLoading(true);try {const data = { title: 'foo', body: 'bar', userId: 1 };const res = await api.post('/posts', data);setResponse(res.data);} catch (error) {console.error(error);alert('请求失败');} finally {setLoading(false);}};return (<View style={styles.container}><Button title="Post Data" onPress={handlePost} />{loading && <ActivityIndicator size="large" color="#0000ff" />}{response && (<View style={styles.responseContainer}><Text style={styles.responseText}>Response:</Text><Text>{JSON.stringify(response)}</Text></View>)}</View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',padding: 20,},responseContainer: {marginTop: 20,padding: 10,backgroundColor: '#f0f0f0',borderRadius: 5,},responseText: {fontSize: 16,fontWeight: 'bold',marginBottom: 5,},
});export default PostData;

解释:

  • 创建 axios 实例:

    • 使用 axios.create 创建一个 axios 实例,并设置 baseURL
  • 请求拦截器:

    • 在请求发送前添加 Authorization 请求头。
  • 响应拦截器:

    • 在响应返回后进行统一处理,例如处理错误码、格式化数据等。
  • 使用 axios 实例:

    • 在组件中使用 api.post 发送请求,无需重复添加请求头。
1.3.4 取消请求

axios 支持取消请求,可以通过 CancelToken 实现。

示例:

// components/CancelablePost.js
import React, { useState } from 'react';
import { View, Text, Button, StyleSheet, ActivityIndicator } from 'react-native';
import axios from 'axios';const CancelablePost = () => {const [response, setResponse] = useState(null);const [loading, setLoading] = useState(false);let cancelToken;const handlePost = async () => {setLoading(true);cancelToken = axios.CancelToken.source();try {const data = { title: 'foo', body: 'bar', userId: 1 };const res = await axios.post('https://jsonplaceholder.typicode.com/posts', data, {cancelToken: cancelToken.token,});setResponse(res.data);} catch (error) {if (axios.isCancel(error)) {console.log('请求取消');} else {console.error(error);alert('请求失败');}} finally {setLoading(false);}};const handleCancel = () => {if (cancelToken) {cancelToken.cancel('用户取消请求');}};return (<View style={styles.container}><Button title="Post Data" onPress={handlePost} /><Button title="Cancel Request" onPress={handleCancel} />{loading && <ActivityIndicator size="large" color="#0000ff" />}{response && (<View style={styles.responseContainer}><Text style={styles.responseText}>Response:</Text><Text>{JSON.stringify(response)}</Text></View>)}</View>);
};const styles = StyleSheet.create({container: {flex: 1,justifyContent: 'center',alignItems: 'center',padding: 20,},responseContainer: {marginTop: 20,padding: 10,backgroundColor: '#f0f0f0',borderRadius: 5,},responseText: {fontSize: 16,fontWeight: 'bold',marginBottom: 5,},
});export default CancelablePost;

解释:

  • 取消请求:
    • 使用 CancelToken.source() 创建一个取消令牌。
    • 在发送请求时,将取消令牌传递给 axios.post
    • 通过调用 cancelToken.cancel('用户取消请求') 可以取消请求。

作者简介

前腾讯电子签的前端负责人,现 whentimes tech CTO,专注于前端技术的大咖一枚!一路走来,从小屏到大屏,从 Web 到移动,什么前端难题都见过。热衷于用技术打磨产品,带领团队把复杂的事情做到极简,体验做到极致。喜欢探索新技术,也爱分享一些实战经验,帮助大家少走弯路!

温馨提示:可搜老码小张公号联系导师

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/886340.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【插件】重复执行 pytest-repeat

安装 pip3 install pytest-repeat 用法 1.命令行 pytest --count num pytest --count 32.装饰器 pytest.mark.repeat(num) #num运行次数 pytest.mark.repeat(5)#执行结果如下&#xff1a;

软件测试 —— 自动化基础

目录 前言 一、Web 自动化测试 1.什么是 Web 自动化测试 2.驱动 3.安装驱动管理 二、Selenium 1.简单 web 自动化测试示例 2.工作原理 三、元素定位 1.cssSelector 2.XPath 四、操作测试对象 1.点击/提交对象 2.模拟按键输入 3.清除文本内容 4.获取文本信息 5.…

Docker+Django项目部署-从Linux+Windows实战

一、概述 1. 什么是Docker Docker 是一个开源的应用容器引擎&#xff0c;支持在win、mac、Linux系统上进行安装。可以帮助我们在一台电脑上创建出多个隔离的环境&#xff0c;比传统的虚拟机极大的节省资源 。 为什么要创建隔离的环境&#xff1f; 假设你先在有一个centos7.…

深度学习工具和框架详细指南:PyTorch、TensorFlow、Keras

引言 在深度学习的世界中&#xff0c;PyTorch、TensorFlow和Keras是最受欢迎的工具和框架&#xff0c;它们为研究者和开发者提供了强大且易于使用的接口。在本文中&#xff0c;我们将深入探索这三个框架&#xff0c;涵盖如何用它们实现经典深度学习模型&#xff0c;并通过代码…

蓝桥杯-洛谷刷题-day3(C++)

目录 1.忽略回车的字符串输入 i.getline() ii.逐个字符的识别再输入 2.获取绝对值abs() 3.做题时的误区 4.多个变量的某一个到达判断条件 i.max() 5.[NOIP2016 提高组] 玩具谜题 i.代码 6.逻辑上的圆圈 i.有限个数n的数组 7.数组的定义 i.动态数组 1.忽略回车的字符串输…

元器件封装

元器件封装类型 为什么越来越多用贴片元件&#xff0c;而不是插件元件 为什么越来越多用贴片元件&#xff0c;而不是插件元件 1.体积小、质量小、容易保存和运输&#xff1b; 2.容易焊接和拆卸。抗震效果好。 贴片元件不用过孔&#xff0c;用锡少。直插元件最麻烦的就是拆卸&a…

C++ 的发展

目录 C 的发展总结&#xff1a;​编辑 1. C 的早期发展&#xff08;1979-1985&#xff09; 2. C 标准化过程&#xff08;1985-1998&#xff09; 3. C 标准演化&#xff08;2003-2011&#xff09; 4. C11&#xff08;2011年&#xff09; 5. C14&#xff08;2014年&#xf…

【MySQL】MySQL在Centos环境安装

&#x1f525;个人主页&#xff1a; Forcible Bug Maker &#x1f525;专栏&#xff1a; MySQL 目录 &#x1f308;前言&#x1f525;卸载不要的环境&#x1f525;检查系统安装包&#x1f525;卸载这些默认安装包&#x1f525;获取mysql官方yum源&#x1f525;安装mysql yum源…

【算法】动态规划中01背包问题解析

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…

Linux开发工具:Vim 与 gcc,打造高效编程的魔法双剑

文章目录 一、初识Vim模式 二、vim基本操作2.1基础操作2.2命令模式/正常模式2.2.1光标定位2.2.2复制粘贴、删除2.2.3撤销2.2.4替换字符2.2.5替换模式 2.3底行模式2.3.1退出vim和**保存文件**2.3.2定位文本字符串2.3.3命令2.3.4实现分屏2.3.5替换指定字符串 2.4补充指令2.4.1视图…

[JAVA]MyBatis框架—如何获取SqlSession对象实现数据交互(基础篇)

假设我们要查询数据库的用户信息&#xff0c;在MyBatis框架中&#xff0c;首先需要通过SqlSessionFactory创建SqlSession&#xff0c;然后才能使用SqlSession获取对应的Mapper接口&#xff0c;进而执行查询操作 在前一章我们学习了如何创建MyBatis的配置文件mybatis.config.xm…

Linux基础开发工具使用

目录 1. 软件包管理器yum 1.1 概念介绍 1.2 更换镜像源&#xff08;可选&#xff09; 1.3 工具的搜索/查看/安装/卸载 1.4 优势 2. vim编辑器 2.1 vi和vim 2.2 三种常用模式和操作 2.3 配置vim 3. Linux编译器-gcc/g 4. Linux调试器-gdb 5. make和Makefile 6.…

群控系统服务端开发模式-应用开发-前端图片格式功能开发

一、添加视图 在根目录下src文件夹下views文件夹下param文件夹下grade文件夹下&#xff0c;新建index.vue&#xff0c;代码如下 <template><div class"app-container"><div class"filter-container" style"float:left;"><…

【WPF】Prism库学习(一)

Prism介绍 1. Prism框架概述&#xff1a; Prism是一个用于构建松耦合、可维护和可测试的XAML应用程序的框架。它支持WPF、.NET MAUI、Uno Platform和Xamarin Forms等多个平台。对于每个平台&#xff0c;Prism都有单独的发布版本&#xff0c;并且它们在不同的时间线上独立开发。…

The Planets: Earth -- 练习

环境搭建 该靶场环境来自Vulnhub -------- Difficulty: Easy 靶机与Kali的IP地址只需要在同一局域网即可&#xff08;同一个网段,即两虚拟机处于同一网络模式&#xff09;&#xff0c;所以需要调整KALI和靶场的网络模式&#xff0c;为了方便测试本地采用NAT模式。 注意&…

C/C++语言基础--initializer_list表达式、tuple元组、pair对组简介

本专栏目的 更新C/C的基础语法&#xff0c;包括C的一些新特性 前言 initializer_list表达式、tuple元组、pair对组再C日常还是比较常用的&#xff0c;尤其是对组在刷算法还是挺好用的&#xff0c;这里做一个简介&#xff1b;这三个语法结合C17的结构化绑定会更好用&#xff…

『VUE』27. 透传属性与inheritAttrs(详细图文注释)

目录 什么是透传属性&#xff08;Forwarding Attributes&#xff09;使用条件唯一根节点禁用透传属性继承总结 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 欢迎关注 『VUE』 专栏&#xff0c;持续更新中 什么是透传属性&#xff08;Forwarding Attributes&#xff09; 在 V…

演员王子辰—专注革命题材 《前行者》后再出发

2021年10月22日在北京卫视播出的由张鲁一、聂远等人主演的电视剧《前行者》&#xff0c;讲述了在二十世纪三十年代初&#xff0c;因叛徒出卖&#xff0c;我上海地下党组织遭到严重破坏&#xff0c;革命事业陷入一片白色恐怖之中。我党情报员马天目刚从法国归来&#xff0c;临危…

【电脑】解决DiskGenius调整分区大小时报错“文件使用的簇被标记为空闲或与其它文件有交叉”

【电脑】解决DiskGenius调整分区大小时报错“文件使用的簇被标记为空闲或与其它文件有交叉” 零、报错 在使用DiskGenius对磁盘分区进行调整时&#xff0c;DiskGenius检查出磁盘报错&#xff0c;报错信息&#xff1a;文件使用的簇被标记为空闲或与其它文件有交叉&#xff0c;…

远程控制步骤

当远在千里之外的朋友想求助你帮他找到他电脑上的文件、或者是给他安装软件时。但是你给他说了他又找不到&#xff0c;那么这时你就可以通过控制对方的电脑去做一系列的操作。 如何远程控制对方的电脑非常关键。 方法一&#xff08;Windows自带远程桌面功能&#xff09;&#…