专栏首页RN 技术react-native-easy-app 详解与使用之(一) AsyncStorage
原创

react-native-easy-app 详解与使用之(一) AsyncStorage

react-native-easy-app 是一款为React Native App快速开发提供基础服务的纯JS库(支持 IOS & Android),特别是在从0到1的项目搭建初期,至少可以为开发者减少30%的工作量。

react-native-easy-app 主要做了这些工作:

1. 对AsyncStorage进行封装,开发者只需几行代码即可实现一个持久化数据管理器。

2. 对fetch进行封装,使得开发者只需关注当前App的前后台交互逻辑和协议,定义好参数设置及解析逻辑即可。

3. 重新封装了RN的View、Text、Image、FlatList 使用得这些控件在适当的时候支持事件或支持icon与文本,能有效减少布局中的嵌套逻辑。

4. 通过设置一个屏幕参考尺寸,重置XView、XText、XImage的尺寸,实现自动多屏适配

可能有人觉得,RN的AsyncStorage本身就很简单,自己封装也就几十行代码的工作量,为什么还要使用第三方库?

一千个人心中,有一千个哈姆雷特,也许我的封装思路能给你带来不一样的启发也未可知呢?

数据存储(AsyncStorage)

RN平台提供的AsyncStorage有一些基础方法:setItem,getItem,removeItem,getAllKeys,这些是promise模式的并且AsyncStorage只支持对纯字符串的存取,因此我们不便于直接在代码中去直接调用这些方法,我们得对AsyncStorage做一次封装,怎样封装能使我们更方便快捷的访问本地存取呢?

我们来看下通过 react-native-easy-app 库的XStorage,我们可以怎样访问AsyncStorage:

1、核心代码实现
import { XStorage } from 'react-native-easy-app';
import { AsyncStorage } from 'react-native';

let RNStorage = { // 自定义对象
    hasLogin: undefined,
    customerId: undefined,
    userInfo: undefined
};
XXStorage.initStorage(RNStorage, AsyncStorage, () => { // 初始化自定义数据管理器
    RNStorage.customerId = '123456';
    RNStorage.hasLogin = true;
    RNStorage.userInfo = {name: 'zhangsan', age: 30};
    console.log(JSON.stringify(RNStorage)) // 打印数据管理器的内容
})

执行完上面的代码后我们看看控制台输出:

console.png

再通过Root Explorer 查看一下当前App的data/data/{package}/database 下数据表的内容:

root_explorer.png

?什么?上面的代码中并没有做任何数据库的存储操作啊,为什么赋值给RNStorage的数据却被存到了本地数据库中呢?我们先看上面的代码中做了什么:

  1. 定义了一个自定义对象RNStorage
  2. 将自定义对象传给RFStorage.initStorage 进行初始化
  3. 在初始化完成后对RNStorage的属性进行了赋值
  4. 打印RNStorage的内容

哦,原来 XStorage 通过getter、setter生成器,将用户自定义的 RNStorage 的各属与 AsyncStorage 的数据表各字段的值进行了关联形成了一个绑定关系,在当用户对 RNStorage 的各属性进行赋值、取值操作的时候,实际上会触发getter、setter生成器,相应的会对 AsyncStorage 中的数据表进行读写操作。

  • 源代码 1
Object.keys(targetObj).map(key => {
    const keyStr = newKey(Tag, key);
    Object.defineProperty(targetObj, key, {
        get: () => {
            return this[keyStr]
        },
        set: (value) => {
            try {
                this[keyStr] = value;
                const valueStr = (typeof value === 'object') ? JSON.stringify(value) : String(value);
                keyValuesPairs.push([keyStr, valueStr])
            } catch (exception) {
                console.log(exception && exception.message);
            }
        },
    })
});
setInterval(() => {
    if (!isEmpty(keyValuesPairs)) {
        let saveDataArray = [...keyValuesPairs];
        keyValuesPairs = []; //清空原键值对数组
        AsyncStorage.multiSet(saveDataArray, () => {
            dataChangedCallback && dataChangedCallback(saveDataArray)
        });
    }
}, 2500)
  • 源代码 2
const Keys = Object.keys(storageObj);
const StorageKeys = Keys.map(key => newKey(Tag, key));
// 初始化时,将AsyncStorage中的数据一次性读取到内存中
AsyncStorage.multiGet(StorageKeys).then(keyValuePairs => {
    keyValuePairs.map(([keyStr, value]) => {
        let [, key] = keyStr.split(splitTag);
        if (persistTag !== key && !isEmpty(value)) {
            storageObj[key] = convertData(value)
        }
    });
    setTimeout(() => initializedCallback(), 100)
}).catch(error => {
    console.log(error)
})

哦,原来 RFStorage 通过getter、setter生成器,将用户自定义的 RNStorage 的各属与 AsyncStorage 的数据表各字段的值进行了关联形成了一个绑定关系,在当用户对 RNStorage 的各属性进行赋值、取值操作的时候,实际上会触发getter、setter生成器,相应的会对 AsyncStorage 中的数据表进行读写操作。

效率与性能的平衡

  • <读> 在初始化XStorage的时候就将AsyncStorage中的所有字段一次性读取到 RNStorage 对象中,以后续读取属性时,并不需要经过AsyncStorage,而是直接返回 RNStorage的属性。
  • <写> 在开发者修改XStorage的属性值时,会先将目标数据赋值给XStorage的属性,然后再异步通过AsyncStorage将目标数据写入到数据库中(考虑到数据写入的效率与性能问题,目前的处理方式为:每次数值的变更都会记录下来,定时程序每隔2.5秒进行一次数据批量写入操作),但这个丝毫不会影响App对数据的操作,因为RNStorage中的数据是实时且同步的。

至此就完全清楚了,是不是很简单?开发者通过 react-native-easy-app 只需定义一个全局可导出的 RNStorage对象(命名随意,并定义好App所需的各属性字段),然后在App启动的时候通过XStorage初始化一次RNStorage即可,以后直接访问RNStorage中的属性值就行了(所有对RNStorage属性的修改都会被自动同步到AsyncStorage中),完全是一劳永逸啊。。。

react-native-easy-app 详解与使用之(二) fetch

想进一步了解,请移步至 npm 或github查看 react-native-easy-app,有源码及使用示例,待大家一探究竟,欢迎朋友们 Star!

如果有任何疑问,欢迎扫码加入RN技术QQ交流群

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 一分钟实现,一个RN持久数据管理器

    在React Native开发过程中,总避免不了需要存储一些数据在本地。对于大多数应用只需要存储一些结构简单的数据,如标记位,用户信息等。这时候我们首选择的存储...

    rufeng008
  • react-native-easy-app 详解与使用之(四)屏幕适配

    react-native-easy-app 是一款为React Native App快速开发提供基础服务的纯JS库(支持 IOS & Android),特别是在...

    rufeng008
  • 五分钟实现,一个RN App开发调试工具

    在React Native开发过程中,做为开发人员,我们经常做着费力不“讨好”的事情,这样占用我们不少时间:

    rufeng008
  • GitHub配置示例

    GitHub官方的Git Shell和GitHub for Windows配置示例,配置文件“.gitconfig”位于用户主目录下,假设用户名为zhangsa...

    一见
  • 解决Intellij IDEA部署JavaWeb项目 404问题

    首先你要保证 你和同事的版本保持一致 jdk 和 tomcat 重中之重 检查一下Project Structure的配置,首先是project:

    崔笑颜
  • Android悬浮窗不用动态申请权限方法

    前几天我刚写了一篇《Android实现可移动的悬浮窗》的文章,需要在AndroidManifest.xml里的加上权限申请

    Vaccae
  • Kafka异常复盘NotLeaderForPartitionException【实战笔记】

    监控及Kafka Manager显示节点数量正常。问题集群有6个节点,3个副本。查看日志发现,都在大量输出选举的日志,日志中暂时没有发现明显的ERROR和FAT...

    瓜农老梁
  • 北漂你后悔了吗?“失败”的北漂十年经历,真的尽力了...

    在我离开北京的时候,我还依稀记得,十年前我对朋友说过的那句话:我一定要留在北京,因为那里有梦想。

    纯洁的微笑
  • 手把手带你在Centos7.5上编译安装openGauss数据库

    openGauss于6月30号开源,继承于原来的GaussDB300的内核,最初源于pg9.2.4内核,但是对pg内核做了很多改动,具体可以参考我这篇文章《华为...

    数据库架构之美
  • SQL基础--> 数据处理(DML、RETURNING、MERGE INTO)

    --=================================================

    Leshami

扫码关注云+社区

领取腾讯云代金券