Back

reactnative - 12. 持久化(存储)

发布时间: 2018-12-24 05:45:00

参考:https://facebook.github.io/react-native/docs/asyncstorage#docsNav

持久化官方提供了这个组件: asyncstorage . 

正常的读取,(例如android中)是同步的, 例如 先进入到某个大方法, 再读取文件,然后再下一步的操作。   

这个则是异步的。 使用了 promise  ( do().then().then()...)  (先读取文件, 再调用某个大方法的操作)

所以,使用的时候要换一下思路。

建议不理解 async , promise ,then的同学,先看这个很简单的介绍文章:

http://siwei.me/blog/posts/es6-async-await-promise-then

经过测试, react 中的读取文件和写入文件的时间大约在10~15ms . 所以可能这也是为什么会有 asyncstore这样的技术出现把。

新建文件:

import React,  { Component} from 'react';
import {Image, Platform, StyleSheet, Text, View, Button, Alert} from 'react-native'
import { AsyncStorage } from "react-native"

export default class AutoStorageDemo extends Component{

  constructor(props){
    super(props)
    this.state = {
      count: ''
    }
    this.setStateAndVisitTimes()
  }

  // 初始化 计数器
  setStateAndVisitTimes = async () => {
    count = parseInt(await AsyncStorage.getItem("count")  || 0 ) + 1
    this.setState({
      count: count
    })
    await AsyncStorage.setItem("count", count + "")
  }

  render() {
      return(
        
          这是您的第{this.state.count}次访问本页面 
        
      )
  }
}

 需要注意的是: 

1. setItem(key, value) 中的value , 必须是 string , 否则会报错

2. getItem 得到的结果,也是 string 

所以这里必须要做转换。

下面是一个手动操作存储的版本:

需要注意的是:

1. 使用 arrow function 来代替 bind(this)

2. async 函数在调用的时候, 不能省略await

    import React,  { Component} from 'react';
    import {Image, Platform, StyleSheet, Text, View, Button, Alert} from 'react-native'
    import { AsyncStorage } from "react-native"

    export default class ManualStorageDemo extends Component{

      constructor(props){
        super(props)
        this.state = {
          isLoaded: false,
          manual_count: ''
        }
      }

      // 没有使用箭头符号, 那么在View中就要  .bind(this) , 否则会报错  this.setState 找不到
      async readData () {
        try{
          const manual_count = await AsyncStorage.getItem("manual_count") || '0'
          if(isNaN(manual_count)){
            manual_count = 1
          }
          this.setState({
            isLoaded: true,
            manual_count: manual_count
          })
        }catch(error){
          console.error(error)
        }

      }

      // 使用箭头符号,就可以在view中调用的时候,不写  .bind(this)
      mySaveThenAlert = async () => {
      // async mySaveThenAlert(){
        try{
          await AsyncStorage.setItem("manual_count", 888 +"")
          const manual_count = await AsyncStorage.getItem("manual_count")
          this.setState({
            isLoaded: true,
            manual_count: manual_count
          })
          Alert.alert("您设置成的手动干预的计数器: " + manual_count)
        }catch(error){
          console.error(error)
        }
      }

      render() {

        if(this.state.isLoaded){
          return(
            <View>
              <Text>页面加载成功!</Text>
              <Text>访问次数: {this.state.manual_count} </Text>
            </View>
          )
        }else{
          return(
            <View>
              <Text>尚未加载成功,请点击下面的按钮进行手动加载 ... </Text>
              <Button
                title="手动加载"
                onPress={this.readData.bind(this)} />
              <Button
                title="手动干预:修改访问次数为 + 888"
                onPress={this.mySaveThenAlert} />
            </View>
          )
        }

      }
    }

Back