
做React Native开发时,网络请求是绕不开的环节——不管是拉取商品列表、提交用户信息,还是同步数据,都得和后端接口打交道,Axios作为当下流行的HTTP客户端,在Web端和React Native里都很常用,但刚接触RN的同学,常会纠结“咋在RN里用Axios发请求?配置、拦截、报错处理这些咋搞?”今天就从基础到实战,把Axios在React Native里的用法拆明白,解决你开发里的痛点~
Axios是啥?在React Native里为啥选它?
Axios是基于Promise的HTTP客户端,能在浏览器、Node.js(React Native也适用)环境发请求,RN本身有内置的fetch API,选Axios主要因为这些优势:
API更简洁:
fetch需要手动解析JSON(res.json())、自己写超时逻辑;Axios自动把响应转JSON,还能直接配置超时时间。拦截器省代码:能在“请求发出去前”“响应回来后”统一处理逻辑(比如加token、处理通用错误),项目里重复代码能少一大半。
错误处理更直观:Axios把网络错误、状态码错误(如404、500)都封装成Promise的
reject,配合try/catch或.catch()很顺手;fetch得自己判断status是否成功。取消请求更方便:用
AbortController或Axios自带的取消令牌,能轻松终止重复请求,避免性能问题。
举个简单对比,用fetch发GET请求得这么写:
fetch('https://api.example.com/data')
.then(res => {
if (!res.ok) throw new Error('请求失败');
return res.json();
})
.then(data => console.log(data))
.catch(err => console.error(err));而Axios一行代码更简洁:
axios.get('https://api.example.com/data')
.then(res => console.log(res.data))
.catch(err => console.error(err));能看出Axios把很多繁琐步骤封装了,开发效率更高。
怎么在React Native项目里引入Axios?
分两步完成安装和基础配置:
第一步:安装Axios依赖
打开终端,进入RN项目根目录,用npm或yarn安装:
# npm npm install axios --save # yarn yarn add axios
第二步:在代码里引入并配置基础项
在需要发请求的文件里导入Axios:
import axios from 'axios';
如果项目里所有请求都要同一个基础地址(baseURL)、超时时间,建议创建自定义Axios实例(避免重复写配置),比如新建api.js:
import axios from 'axios';
// 创建自定义实例,配置通用参数
const instance = axios.create({
baseURL: 'https://your-api-domain.com/api/', // 后端接口基础地址
timeout: 10000, // 超时时间(毫秒)
headers: {
'Content-Type': 'application/json', // 默认请求头
// 也可以加通用Authorization(但登录前可能没token,后续用拦截器更灵活)
}
});
export default instance;之后在组件里用这个实例发请求,路径会自动拼接baseURL:
import api from './api'; // 导入封装好的实例
const fetchData = () => {
api.get('/user/list') // 实际请求地址:https://your-api-domain.com/api/user/list
.then(res => { /* 处理数据 */ })
.catch(err => { /* 处理错误 */ });
};常用的请求方法咋写?(GET/POST等)
不同请求场景(查数据、提交数据)对应不同方法,逐个拆解:
GET请求:获取数据
场景1:带查询参数(?page=1&size=10)
把参数放params里,Axios会自动拼到URL后:
// 示例:获取用户列表(带分页参数)
api.get('/user/list', {
params: {
page: 1,
size: 10
}
})
.then(res => console.log(res.data))
.catch(err => console.error('获取列表失败:', err));场景2:路径参数(/user/{id})
如果接口是/user/123这种形式,直接用模板字符串拼路径:
const userId = 123;
api.get(`/user/${userId}`)
.then(res => { /* 处理单个用户数据 */ });POST请求:提交/新增数据
场景1:发送JSON数据
后端需JSON格式时,直接把数据放data里(Axios自动设Content-Type: application/json):
// 示例:用户注册(提交账号密码)
const userInfo = { username: 'test', password: '123456' };
api.post('/user/register', userInfo)
.then(res => console.log('注册成功,返回:', res.data))
.catch(err => console.error('注册失败:', err.response?.data || err.message));场景2:发送表单数据(Form Data)
若后端需multipart/form-data(比如上传文件),手动创建FormData:
import { FormData } from 'react-native'; // RN的FormData
const uploadAvatar = () => {
const formData = new FormData();
formData.append('file', {
uri: 'file:///path/to/avatar.jpg', // 文件本地路径
name: 'avatar.jpg',
type: 'image/jpeg'
});
formData.append('userId', '123'); // 其他表单字段
api.post('/upload/avatar', formData, {
headers: { 'Content-Type': 'multipart/form-data' } // 手动设请求头
})
.then(res => console.log('上传成功,新地址:', res.data.url))
.catch(err => console.error('上传失败:', err));
};PUT/PATCH/DELETE请求
这几个方法用法和POST类似,根据后端RESTful风格选:
PUT:全量更新资源(如替换整个用户信息)PATCH:局部更新(如只改用户昵称)DELETE:删除资源
示例(PATCH更新用户昵称):
const updateNickname = () => {
const newNickname = { nickname: '新昵称' };
api.patch(`/user/${userId}`, newNickname)
.then(res => console.log('昵称更新成功', res.data))
.catch(err => { /* 处理错误 */ });
};拦截器有啥用?怎么给请求加统一处理?
拦截器是Axios的“核心优势”——能在请求发出去前和响应回来后插入逻辑,减少重复代码。
请求拦截器:给所有请求加token、统一header
项目里登录后需带token?在请求拦截器里统一加:
// 回到封装的api.js,给instance加拦截器
instance.interceptors.request.use(
config => {
// 从本地取token(假设用AsyncStorage存储)
const token = AsyncStorage.getItem('token');
if (token) {
config.headers.Authorization = `Bearer ${token}`; // token加到请求头
}
return config; // 必须返回config,否则请求发不出去
},
error => Promise.reject(error) // 请求前出错,直接抛错
);这样所有用instance的请求,都会自动带token,不用每个请求写headers。
响应拦截器:处理通用错误、数据格式化
后端返回通常有统一格式(如{ code, msg, data }),用响应拦截器统一处理:
instance.interceptors.response.use(
response => {
// 假设后端约定code=200为成功
if (response.data.code !== 200) {
// 业务错误抛给catch处理
return Promise.reject(new Error(response.data.msg || '业务请求失败'));
}
return response.data.data; // 直接返回实际业务数据,简化后续调用
},
error => {
// 处理网络/状态码错误
if (error.response) {
// 服务器返回错误(状态码非2xx)
console.error('响应错误,状态码:', error.response.status);
console.error('错误信息:', error.response.data);
} else if (error.request) {
// 请求发了但没响应(超时、断网)
console.error('请求超时或无响应:', error.request);
} else {
// 请求配置错误
console.error('请求配置错误:', error.message);
}
return Promise.reject(error); // 错误抛给业务代码
}
);配置后,业务代码调用接口时,直接拿到response.data.data(实际数据);只要code不对,会直接进catch,不用每个请求判断code,效率翻倍~
网络请求出错了咋处理?
Axios的错误分三类,针对性处理更高效:
情况1:网络错误(没网、超时)
用户断网或请求超时(配置了timeout但后端没响应)时,error.request有信息,error.response为undefined。
业务代码里判断:
api.get('/data')
.then(data => { /* 成功 */ })
.catch(err => {
if (err.request) {
alert('网络不给力,请检查连接~');
} else {
alert('请求出错:' + err.message);
}
});情况2:状态码错误(404、500等)
后端返回状态码非2xx(如401未授权、404资源不存在),error.response存在,含status、data等信息。
可在响应拦截器或业务代码里根据status提示:
.catch(err => {
if (err.response) {
const status = err.response.status;
if (status === 401) {
alert('登录过期,请重新登录~');
// 跳转到登录页等逻辑
} else if (status === 404) {
alert('请求的资源不存在~');
} else {
alert('服务器出错了,请稍后再试~');
}
}
});情况3:业务错误(code≠200)
后端用code表示业务状态(如code=4001代表“用户名已存在”),响应拦截器已把这种情况抛为Promise.reject,业务代码catch后提示msg:
api.post('/user/register', { username: 'test' })
.then(data => { /* 成功 */ })
.catch(err => {
if (err.message === '用户名已存在') {
alert('该用户名已被注册,请换一个~');
} else {
alert('注册失败:' + err.message);
}
});怎么优化Axios请求的性能和体验?
光会发请求不够,得考虑性能和用户体验,比如避免重复请求、加loading、缓存数据等。
取消重复请求:避免多次请求同一接口
用户快速点击“刷新”时,用AbortController取消之前的请求:
import { AbortController } from 'react-native'; // RN的AbortController
let abortController = null;
const fetchData = () => {
// 取消未完成的请求
if (abortController) abortController.abort();
abortController = new AbortController();
api.get('/data', { signal: abortController.signal })
.then(data => { /* 处理数据 */ })
.catch(err => {
if (err.name === 'AbortError') {
console.log('请求被取消');
} else {
// 处理其他错误
}
});
};连续点击时,只会保留最后一次请求,减少资源浪费。
请求缓存:避免重复拉取相同数据
对不常变化的接口(如首页轮播图),用Map或AsyncStorage缓存:
const cache = new Map();
const fetchBanner = () => {
const cacheKey = 'banner-data';
if (cache.has(cacheKey)) {
return Promise.resolve(cache.get(cacheKey)); // 直接返回缓存
}
return api.get('/banner')
.then(data => {
cache.set(cacheKey, data); // 存入缓存
return data;
});
};管理loading状态:提升用户体验
发请求时显示loading,结束后隐藏,结合React Hook(如useState)很方便:
import { useState } from 'react';
import { View, ActivityIndicator, Button, FlatList } from 'react-native';
const HomeScreen = () => {
const [isLoading, setIsLoading] = useState(false);
const [bannerData, setBannerData] = useState([]);
const fetchBanner = () => {
setIsLoading(true);
api.get('/banner')
.then(data => {
setBannerData(data);
setIsLoading(false);
})
.catch(err => {
setIsLoading(false);
alert('获取轮播图失败');
});
};
return (
<View>
{isLoading ? (
<ActivityIndicator />
) : (
<FlatList
data={bannerData}
renderItem={({ item }) => <BannerItem item={item} />}
/>
)}
<Button title="刷新" onPress={fetchBanner} />
</View>
);
};实战场景:登录功能里的Axios调用咋做?
以“用户登录”为例,串起前面知识点:
步骤1:搭建登录界面
用TextInput输入账号、密码,Button触发登录:
import { View, TextInput, Button, Alert } from 'react-native';
import { useState } from 'react';
import api from './api'; // 封装好的Axios实例
const LoginScreen = ({ navigation }) => {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLogin = () => {
// 登录逻辑写这里
};
return (
<View>
<TextInput
placeholder="用户名"
value={username}
onChangeText={setUsername}
/>
<TextInput
placeholder="密码"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<Button title="登录" onPress={handleLogin} />
</View>
);
};步骤2:发起登录请求(POST)
在handleLogin里发请求,处理成功/失败:
const handleLogin = () => {
if (!username || !password) {
Alert.alert('提示', '请填写账号和密码~');
return;
}
api.post('/user/login', { username, password })
.then(res => {
// 登录成功,res是响应拦截器处理后的数据(假设含token、userInfo)
const { token, userInfo } = res;
// 存储token到本地
AsyncStorage.setItem('token', token);
// 跳转到首页
navigation.replace('Home');
Alert.alert('成功', '登录成功~');
})
.catch(err => {
// 处理错误
if (err.response?.data?.msg) {
Alert.alert('失败', err.response.data.msg);
} else {
Alert.alert('失败', '网络或服务器错误,请重试~');
}
});
};步骤3:结合拦截器自动带token
前面封装的api.js请求拦截器,会自动从AsyncStorage取token加到请求头,后续接口(如获取用户信息)无需手动加token,拦截器自动处理~
看完这些,你应该对React Native里用Axios发请求有清晰思路了:从基础安装、请求写法,到拦截器提效、错误处理,再到性能优化和实战场景,每个环节都对应开发里的实际需求,Axios的核心是“简化HTTP请求流程+统一处理逻辑”,结合RN的特性(比如FormData上传文件),能帮你更高效地和后端对接,要是开发中遇到具体问题(比如拦截器配置不生效),可以再针对性排查~现在就把这些技巧用到项目里,让网络请求这块更丝滑吧~





网友评论文明上网理性发言 已有0人参与
发表评论: