7. react-native网络请求与存储技术
react native 官方推荐我们使用Fetch进行网络请求,
React native 引入了fetch,我们可以rn中使用全局fetch()方法进行网络请求,并且不需要自己做额外的导入
注意
- 当接收到一个代表错误的 HTTP 状态码时,从 fetch()返回的 Promise 不会被标记为 reject,即使该 HTTP 响应的状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false),仅当网络故障时或请求被阻止时,才会标记为 reject。
- 默认情况下,fetch 不会从服务端发送或接收任何cookies,如果站点依赖于用户 session,则会导致未经认证的请求(要发送cookies,必须设置 credentials 选项)
简单请求示例
let getData = async() => {
console.log(searchKey, 'searchKey')
let url = `https://api.github.com/search/repositories?q=${searchKey}`;
fetch(url)
.then(res => {
if (res.ok) {
return res.json()
}
throw new Error('请求失败')
})
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err)
})
}
AsyncStorage
什么是?
简单的、异步的、持久化的key-value存储系统
AsyncStorage也是React Native 官方推荐的数据存储方式,旨在代替LocalStorage
在IOS存储为分两种情况:
如果存储内容较小,那么AsyncStorage会将存储的内容放在序列化的字典中
如果存储的值较大,那么AsyncStorage会创建一个单独的文件中
在Android也分为两种情况:
AsyncStorage会将数据存储在RocksDB或者SQLite,具体存储哪一种取决于设备支持哪一种存储方式
注意
在0.75版中AsyncStorage 已经被react-native移除,需要用第三方库,但它的方法都是一样的
库地址: https://react-native-async-storage.github.io/async-storage/
存储数据
import { AsyncStoreage } from 'react-native';
or
import AsyncStorage from '@react-native-async-storage/async-storage';
async doSave() {
// 用法1
AsyncStorage.setItem(KEY, value, error => {
error && console.log(error.toString());
})
// 用法2
AsyncStorage.setItem(KEY, value).catch(err => {
error && console.log(error.toString());
});
// 用法3
try {
await AsyncStorage.setItem(KEY, value);
} catch (error) {
error && console.log(error.toString());
})
}
读取数据
import { AsyncStoreage } from 'react-native';
async doSave() {
// 用法1
AsyncStorage.getItem(KEY, (error, value) => {
// ....
});
// 用法2
AsyncStorage.getItem(KEY).then(value => {
// ...
}).catch(err => {
error && console.log(error.toString());
});
// 用法3
try {
let value = await AsyncStorage.getItem(KEY);
// ...
} catch (error) {
error && console.log(error.toString());
})
}
删除存储数据
AsyncStorage.removeItem(KEY);
合并或更新代码
AsyncStorage.mergeItem(key: string, value: string, callback?: (error: ?Error) => void): Promise<void>;
- key:需要合并数据的key,类型为string。
- value:需要合并到key下的新数据,注意这里也应该是字符串类型。如果原key下存储的是JSON对象,那么新value也应该是能合并到该JSON对象中的字符串表示的JSON片段
清除值
AsyncStorage.clear();
AsyncStorage.clear()方法并不会删除存储中的密钥(Key),而只是清除与这些密钥相关联的值(Value)。这意味着,即使在使用AsyncStorage.clear()方法清除了存储的数据之后,仍然可以使用相同的密钥来存储新的数据
获取所有存储键的内容
AsyncStorage.getAllKeys((err, keys) => { });
清除所有进行中的查询操作
AsyncStorage.flushGetRequests();
- 取消未完成的查询:当你的应用不再需要获取之前请求的数据时,你可以调用flushGetRequests()来取消这些请求。这有助于减少不必要的资源消耗和潜在的内存泄漏。
- 状态管理:在某些情况下,你可能需要重置AsyncStorage的状态,特别是在处理复杂的异步逻辑或调试时。flushGetRequests()可以帮助你清除当前的所有查询请求,从而更容易地管理状态。
- 性能优化:如果你的应用频繁地发起AsyncStorage查询,并且这些查询可能会因为网络延迟或其他原因而变慢,那么在某些情况下,取消未完成的查询可能会提高应用的性能。
同时获取多个键值
await AsyncStorage.multiGet(['key1', 'key2', 'key3'])
同时存储多个键值对
AsyncStorage.multiSet([
['key1', 'value1'],
['key2', 'value2'],
['key3', 'value3']
]);
同时删除多个键值对
AsyncStorage.multiRemove(['key1', 'key2', 'key3'])
合并更新多个键值对
const keyValuePairsToMerge = [
['key1', '{"existingField1":"newValue1", "newField":"valueX"}'],
['key2', '{"fieldA":"valueA", "fieldB":"valueB"}']
];
await AsyncStorage.multiMerge(keyValuePairsToMerge)
设计离线缓存框架
为什么?
提升用户体验:我们要为用户提供流畅的APP操作体验,但我们无法保证所有用户的网络流畅度都是很好的,所以我们需要离线缓存来提升用户体验
节省流量:
节省服务器流量
节省用户手机的流量
策略
- 优先从本地获取数据,如果数据过时或不存则从服务器获取数据,数据返回后同时将数据同步到本地数据库;
- 优先从服务器获取数据,数据返回后同时将数据同步到本地数据库,如果网络故障则从本地获取数据;
- 同时从本地和服务器获取数据,如果本地数据库返回数据则先展示本地数据,等网络数据回来后在展示网络数据同时将数据同步到本地数据库;