React Native AsyncStorage 存储字符串以外的值

Posted

技术标签:

【中文标题】React Native AsyncStorage 存储字符串以外的值【英文标题】:React Native AsyncStorage storing values other than strings 【发布时间】:2016-06-06 09:22:42 【问题描述】:

除了使用 AsyncStorage 的字符串之外,还有什么方法可以存储值吗?例如,我想存储简单的布尔值。

AsyncStorage.setItem('key', 'ok');

没问题,但是:

AsyncStorage.setItem('key', false);

不工作..

【问题讨论】:

【参考方案1】:

我建议你使用react-native-easy-app,通过它可以同步访问AsyncStorage,也可以存储和检索对象、字符串或布尔数据。

import  XStorage  from 'react-native-easy-app';
import  AsyncStorage  from 'react-native';

export const RNStorage = // RNStorage : custom data store object
     token: undefined, // string type
     isShow: undefined, // bool type
     userInfo: undefined, // object type
 ;   

const initCallback = () => 

     // From now on, you can write or read the variables in RNStorage synchronously

     // equal to [console.log(await AsyncStorage.getItem('isShow'))]
     console.log(RNStorage.isShow); 

     // equal to [ await AsyncStorage.setItem('token',TOKEN1343DN23IDD3PJ2DBF3==') ]
     RNStorage.token = 'TOKEN1343DN23IDD3PJ2DBF3=='; 

     // equal to [ await AsyncStorage.setItem('userInfo',JSON.stringify( name:'rufeng', age:30)) ]
     RNStorage.userInfo = name: 'rufeng', age: 30; 
;

XStorage.initStorage(RNStorage, AsyncStorage, initCallback); 

【讨论】:

【参考方案2】:

我总是围绕 AsyncStorage 使用/创建一个包装器模块,在传入和传出的数据上使用 JSON.parse 和 JSON.stringify。

这样您就无需在业务逻辑中调用 JSON.parse 和 JSON.stringify。这使代码看起来更好看。

类似

import AsyncStorage from "@react-native-community/async-storage";

export const Storage 

    getItem: async (key) => 
        try 
             let result = await AsyncStorage.getItem(key);
             return JSON.parse(result);
         
        catch (e) 
             throw e;
         
    ,

    setItem: async (key, value) => 

        try 
            const item = JSON.stringify(value);

            return await AsyncStorage.setItem(key, item);
         catch (e) 
            throw e;
        
    


// usage

async function usage () 

    const isLeeCool = true;
    const someObject =  name: "Dave" ;
    const someArray = ["Lee", "Is", "Cool."];

    try 
        // Note Async storage has a method where you can set multiple values,
        // that'd be a better bet here (adding it to the wrapper).
        await Storage.setItem("leeIsCool", leeIsCool);
        await Storage.setItem("someObject", someObject);
        await Storage.setItem("someArray", someArray);
      catch (e) 

    // Some point later that day...

    try 

        console.log(await Storage.getItem("leeIsCool"));
        console.log(await Storage.getItem("someObject"));
        console.log(await Storage.getItem("someArray"));
      catch (e) 

【讨论】:

【参考方案3】:
 await AsyncStorage.setItem('saveUserCredential', JSON.stringify(true/false), () => 
        console.log("saveUserCredential save details " +flag);
 );



  AsyncStorage.getItem('saveUserCredential').then(async (value) => 
               let userLogin = await JSON.parse(value);

               if(userLogin )
                   this.props.navigation.navigate("HomeScreen");
               else 
                  this.props.navigation.navigate("LoginScreen");
               
           );

【讨论】:

【参考方案4】:

基于AsyncStorage React-native docs,恐怕你只能存储字符串..

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

设置键的值并在完成时调用回调,以及 如果有错误。返回一个 Promise 对象。

您可能想尝试查看第三方软件包。也许this one。

编辑 02/11/2016

感谢@Stinodes 提供的技巧。

虽然只能存储字符串,但也可以用 JSON 对对象和数组进行字符串化存储,取回后再解析。

这仅适用于普通的对象实例或数组,但是,从任何原型继承的对象可能会导致意外问题。

一个例子:

// Saves to storage as a JSON-string
AsyncStorage.setItem('key', JSON.stringify(false))

// Retrieves from storage as boolean
AsyncStorage.getItem('key', (err, value) => 
    if (err) 
        console.log(err)
     else 
        JSON.parse(value) // boolean false
    
)

【讨论】:

是的,看起来就是这样,尽管我认为它应该比这更好。谢谢。 是的,但是看看第三方库,有些真的很强大和有用。 我将如何存储布尔值。当我对它进行 Stringify 时,我得到了一个 Promise 对象作为回报。【参考方案5】:

您只能存储字符串,但您可以完全使用 JSON 对对象和数组进行字符串化,并在将它们从本地存储中拉出时再次对其进行解析。 不过,这只适用于普通的 Object-instances 或数组。

从任何原型继承的对象都可能导致一些意外行为,因为原型不会被解析为 JSON。

不过,可以使用 JSON.stringify 存储布尔值(或任何原语)。 JSON 可以识别这些类型,并且可以双向解析它们。

JSON.stringify(false) // "false"
JSON.parse("false")   // false

所以:

// Saves to storage as a JSON-string
AsyncStorage.setItem('someBoolean', JSON.stringify(false))

// Retrieves from storage as boolean
AsyncStorage.getItem('someBoolean', function (err, value) 
    JSON.parse(value) // boolean false


// Or if you prefer using Promises
AsyncStorage.getItem('someBoolean')
    .then( function (value) 
        JSON.parse(value) // boolean false
    )


// Or if you prefer using the await syntax
JSON.parse(await AsyncStorage.getItem('someBoolean')) // boolean false

在获取并解析值之后(它不必是布尔值,它可以是一个对象。无论哪个满足您的需要),您可以设置状态或对它做任何事情。

【讨论】:

如果你使用回调而不是promise方式,回调的签名实际上是:function(err, value) => JSON.parse(value) @PatrickBassut 你是对的,我的错。在写下我的答案之前,我愚蠢地没有在他们的文档中确认。不过现在编辑了。谢谢指出【参考方案6】:

我在 AsyncStorage 的“name”键中设置了值

AsyncStorage.setItem("name", "Hello");

从键“name”中获取值

AsyncStorage.getItem("name").then((value) => 
   console.log("Get Value >> ", value);
).done();

输出如下:

'Get Values >> ', 'Hello'

【讨论】:

以上是关于React Native AsyncStorage 存储字符串以外的值的主要内容,如果未能解决你的问题,请参考以下文章

对react native 的AsyncStorage 进行小型封装

使用 React native 不推荐使用 AsyncStorage

React Native AsyncStorage 存储字符串以外的值

React Native React Navigation 屏幕在使用 AsyncStorage 登录后不会重定向

React Native AsyncStorage ')' 以结束复合表达式

React Native 等待 AsyncStorage 获取值