AsyncStorage快速上手

AsyncStorage快速上手

本文章介绍的为@react-native-async-storage/async-storage
目前React中文网:

已过时。 Use one of the community packages instead.

项目官网:https://react-native-async-storage.github.io/async-storage/

特点:

持久化仓库
Async Storage一个React Native的异步、未加密、持久化的Key Value存储解决方案。
多平台支持
适用于Android、iOS、Web、MacOS和Windows的数据存储解决方案。
简洁的API
少量的工具可以简化您的存储流程。轻松保存、读取、合并和删除数据!

Async Storage环境搭建

NPM:

npm install @react-native-async-storage/async-storage

Yarn:

yarn add @react-native-async-storage/async-storage

Expo CLI:

expo install @react-native-async-storage/async-storage

IOS请使用CocoaPods去添加RNAsyncStorage到你的项目

npx pod-install

高版本默认链接,如有链接问题请阅读https://react-native-async-storage.github.io/async-storage/docs/install

API

getItem通过Key获取数据

static getItem(key: string, [callback]: ?(error: ?Error, result: ?string) => void): Promise

Example

getMyObject = async () => {
  try {
    const jsonValue = await AsyncStorage.getItem('@key')
    return jsonValue != null ? JSON.parse(jsonValue) : null
  } catch(e) {
    // read error
  }

  console.log('Done.')
}

setItem存储数据

static setItem(key: string, value: string, [callback]: ?(error: ?Error) => void): Promise

Example:

setObjectValue = async (value) => {
  try {
    const jsonValue = JSON.stringify(value)
    await AsyncStorage.setItem('key', jsonValue)
  } catch(e) {
    // save error
  }

  console.log('Done.')
}

mergeItem合并数据项

static mergeItem(key: string, value: string, [callback]: ?(error: ?Error) => void): Promise

Example:

const USER_1 = {
  name: 'Tom',
  age: 20,
  traits: {
    hair: 'black',
    eyes: 'blue'
  }
}

const USER_2 = {
  name: 'Sarah',
  age: 21,
  hobby: 'cars',
  traits: {
    eyes: 'green',
  }
}


mergeUsers = async () => {
  try {
    //save first user
    await AsyncStorage.setItem('@MyApp_user', JSON.stringify(USER_1))

    // merge USER_2 into saved USER_1
    await AsyncStorage.mergeItem('@MyApp_user', JSON.stringify(USER_2))

    // read merged item
    const currentUser = await AsyncStorage.getItem('@MyApp_user')

    console.log(currentUser)

    // console.log result:
    // {
    //   name: 'Sarah',
    //   age: 21,
    //   hobby: 'cars',
    //   traits: {
    //     eyes: 'green',
    //     hair: 'black'
    //   }
    // }
  }
}

removeItem移除某一项

static removeItem(key: string, [callback]: ?(error: ?Error) => void): Promise

Example

removeValue = async () => {
  try {
    await AsyncStorage.removeItem('@MyApp_key')
  } catch(e) {
    // remove error
  }

  console.log('Done.')
}

getAllKeys获取某一项

static getAllKeys([callback]: ?(error: ?Error, keys: ?Array<string>) => void): Promise

Example

getAllKeys = async () => {
  let keys = []
  try {
    keys = await AsyncStorage.getAllKeys()
  } catch(e) {
    // read key error
  }

  console.log(keys)
  // example console.log result:
  // ['@MyApp_user', '@MyApp_key']
}

multiGet获取多个数据项

static multiGet(keys: Array<string>, [callback]: ?(errors: ?Array<Error>, result: ?Array<Array<string>>) => void): Promise

Example:

getMultiple = async () => {

  let values
  try {
    values = await AsyncStorage.multiGet(['@MyApp_user', '@MyApp_key'])
  } catch(e) {
    // read error
  }
  console.log(values)

  // example console.log output:
  // [ ['@MyApp_user', 'myUserValue'], ['@MyApp_key', 'myKeyValue'] ]
}

multiSet设置多个数据项

static multiSet(keyValuePairs: Array<Array<string>>, [callback]: ?(errors: ?Array<Error>) => void): Promise

Example:

multiSet = async () => {
  const firstPair = ["@MyApp_user", "value_1"]
  const secondPair = ["@MyApp_key", "value_2"]
  try {
    await AsyncStorage.multiSet([firstPair, secondPair])
  } catch(e) {
    //save error
  }

  console.log("Done.")
}

clear清空存储项

static clear([callback]: ?(error: ?Error) => void): Promise

Example:

clearAll = async () => {
  try {
    await AsyncStorage.clear()
  } catch(e) {
    // clear error
  }

  console.log('Done.')
}

useAsyncStorage自动创建基于Key的增删改查

源码:

static useAsyncStorage(key: string): {
  getItem: (
    callback?: ?(error: ?Error, result: string | null) => void,
  ) => Promise<string | null>,
  setItem: (
    value: string,
    callback?: ?(error: ?Error) => void,
  ) => Promise<null>,
  mergeItem: (
    value: string,
    callback?: ?(error: ?Error) => void,
  ) => Promise<null>,
  removeItem: (callback?: ?(error: ?Error) => void) => Promise<null>,
}

返回值:

object

Specific Example:

import React, { useState, useEffect } from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import { useAsyncStorage } from '@react-native-async-storage/async-storage';

export default function App() {
  const [value, setValue] = useState('value');
  const { getItem, setItem } = useAsyncStorage('@storage_key');

  const readItemFromStorage = async () => {
    const item = await getItem();
    setValue(item);
  };

  const writeItemToStorage = async newValue => {
    await setItem(newValue);
    setValue(newValue);
  };

  useEffect(() => {
    readItemFromStorage();
  }, []);

  return (
    <View style={{ margin: 40 }}>
      <Text>Current value: {value}</Text>
      <TouchableOpacity
        onPress={() =>
          writeItemToStorage(
            Math.random()
              .toString(36)
              .substr(2, 5)
          )
        }
      >
        <Text>Update value</Text>
      </TouchableOpacity>
    </View>
  );
}

值得关注的一些特性

Android存储容量限制

参考文档:https://react-native-async-storage.github.io/async-storage/docs/limits

AsyncStorage for Android 使用 SQLite 作为存储后端。虽然它有自己的大小限制,Android 系统也有两个已知的限制:总存储大小和每个条目的大小限制。

  • 默认情况下,总存储大小上限为 6 MB。您可以通过使用功能标志指定新大小来增加此大小
  • 每个条目受 WindowCursor 大小的限制,WindowCursor 是一个用于从 SQLite 读取数据的缓冲区。目前它的大小约为 2 MB。这意味着一次读取的单个项目不能大于 2 MB。AsyncStorage 没有受支持的解决方法。我们建议将您的数据保持在低于该值的水平,将其分成多个条目,而不是一个庞大的条目。这是multiGetmultiSetAPI可以发挥作用的地方。

下一代存储接口

参考文档:https://react-native-async-storage.github.io/async-storage/docs/advanced/next

支持的平台:Android

为何迁移

持久层的当前实现是使用SQLiteOpenHelper创建的,这是一个管理数据库创建和迁移的助手类。即使这种方法很强大,但缺乏编译时查询验证和将 SQLite 查询映射到实际值的大样板,使得这种实现容易出现许多错误。

此异步存储功能改进了持久层,使用现代方法访问 SQLite(使用Room),将可能的异常减少到最低限度。最重要的是,它允许从本机端访问 AsyncStorage,这在Brownfield 集成中很有用

启用
  1. 在您的项目android目录中,找到根build.gradle文件。将 Kotlin 依赖项添加到buildscript
buildscript {
    ext {
        // other extensions
+        kotlinVersion = '1.5.31'
    }
    
    dependencies {
        // other dependencies
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
    }
}
  1. 在同一目录(通常android)中找到gradle.properties文件(如果它不存在,则创建一个)并添加以下行:
AsyncStorage_useNextStorage=true

与RN一起实践

tool.js

export const propertyVerify = (value, warn = "Parameter does not conform to role.", type="string") => {
  if(value == null || value == undefined || value == "" || typeof value != type) {
    console.warn(warn);
    return false;
  }
  return true;
}

connect_store.js

import {propertyVerify} from './tools'
import AsyncStorage,{useAsyncStorage} from '@react-native-async-storage/async-storage';

const _connect = {
  connectedKey : "",
  connectedName : "",
}

export const createConnect = (key="", name="") => {
  if(propertyVerify(name)) {
    _connect.connectedKey = key;
    _connect.connectedName = name;
  }
  return _connect;
}

export const setConnectStorage = async (key, connect) => {
  try {
    const jsonValue = JSON.stringify(connect);
    await AsyncStorage.setItem(key, jsonValue);
  } catch(e) {
    console.error("Set connect storage error!", e);
  }
}

export const getConnectStorage = async (key) => {
  try {
    const value = await AsyncStorage.getItem(key);
    if(value !== null) {
      return value;
    }
  } catch(e) {
    console.error("Get connect storage error!", e);
  }
}

index.js

import React from 'react';
import {View, StyleSheet, Button, Text} from 'react-native';
import {setConnectStorage, getConnectStorage, createConnect} from '../../../app/store/connect_store';

const Index = () => {
  let key = "current_conn";
  const setCurrentConnect = (id, name) => {
    setConnectStorage(key, createConnect(key=id,name=name));
    console.info("Done!")
  }
  const getCurrentConnect = async () => {
    const conn = await getConnectStorage(key);
    console.log(conn, "!!!");
  }
  return (
    <View>
      <Button
        title={"Add Info1"}
         onPress={()=>setCurrentConnect("id9988","TP-link 7188")}
      />
      <Button
        title={"Add Info2"}
         onPress={()=>setCurrentConnect("id9990","TP-link 71885G")}
      />
      <Button
        title={"Get Info"}
        onPress={getCurrentConnect}
      />
    </View>
  );
}

const styles = StyleSheet.create({})

export default Index;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值