React Native(四)数据本地存储

本地数据存储指的是将数据存储在设备中,在需要数据的时候调用,数据并不会因为应用退出,或者网络断开而无法获取。在React Native中常用的存储方式有两种:

  • AsyncStorage:类似iOS中的NSUserDefault,存放在plist文件中,官方推荐由React Native中文网封装维护的react-native-storage模块
  • Realm: 新的移动端数据库王者,据说性能甚至比单独无封装的SQLite还要快
    如果你的应用数据量不大,仅仅需要存储几个用户配置的信息,就用AsyncStorage,否则就用Realm,如何抉择就像你选择NSUserDefault还是SQLite一样

下面举例用到的两个场景
场景1:用户通过用户名和密码登录,返回token,后续的接口请求中,需在请求头部带上token,服务端根据token来识别用户。

一 、安装react-native-storage并全局范围内创建一个storage实例
npm install react-native-storage --save
import { AsyncStorage } from 'react-native';
import Storage from 'react-native-storage';
var storage = new Storage({
    size: 1000,
    storageBackend: AsyncStorage,
    defaultExpires: null,
    enableCache: true,
})
// 全局变量
global.storage = storage
二 、用户登录,存储Token
    fetch_login = () => {
        let params = {
            account: this.username,
            password: this.password,
            client_secret: config.app_client_secret,
            client_id: config.app_client_id
        }
        passport_fetch('users/signin', 'POST', params).then(
            (data) => {
                //存储用户Token
                global.storage.save({
                    key:'token',
                    data: data.access_token,
                    expires: null
                });
                this.refs.toast.show('登录成功');
                this.fetchUserInfo()
            }
        ).catch(
            err=>{
                this.refs.toast.show(err);
            }
        )
    }
三 、接口请求时获取存储的Token信息

passport_fetch 是与帐号相关的网络请求接口,调用时候会从storage获取存储的Token并放入请求头部

const passport_fetch = async (url, method, params = '') => {
    //获取存储Token
    let token= await global.storage.load({
        key:'token'
    })
    let header = {
        "Content-Type": "application/json;charset=UTF-8",
        'platform': 2,
    };
    if (token.length) {
        header['Authorization'] = 'Bearer ' + token
    }
    return new Promise(function (resolve, reject) {
        fetch(common_url + url, {
            method: method,
            headers: header,
            body:JSON.stringify(params)   
        }).then((response) => response.json())
            .then(checkStatus)
            .then((responseData) => {
                resolve(responseData['data']);
            })
            .catch( (err) => {
                console.log('err:',url, err);  
                reject(err);
            });
    });
}

这里需注意的是存储数据的获取,storageload是异步的,正常header以及请求只能写在其then方法中,才能保证请求是在获取到数据之后才进行,如果要保证同步的写法,这里可以采用await伪同步的方式,同时整个函数必须是async的,最后返回一个Promise,比如登录后获取用户信息则会自动带上Token数据

    fetchUserInfo = () => {
        passport_fetch('users/me', 'GET').then(
            () => {
                this.refs.toast.show('获取信息成功');
            }
        ).catch(
            err=>{
                this.refs.toast.show(err);
            }
        )
    }

场景2:app首页加载时候先显示上次请求的数据,避免接口数据请求未返回前页面无数据的尴尬情况

在首页js文件中添加如下代码:
constructor(props) {
     super(props)
      this.state = {
          dataList: this.loadFromLocal(),
       }
       ...
}
//加载缓存数据
loadFromLocal = async () => {
    let list= await storage.load({
        key:'recommendList'
    })
    this.setState({
        dataList: list,
    })
}
fetchRequest('games/recommend', 'GET').then(
    data => {
        let newList = data.map((item) => {
            return {
                imageUrl: item.icon_url,
                ...
            }
        })
        for (let i = 0; i < newList.length; i++) {
            newList[i].id = i
        }
        this.setState({
            dataList: newList,
            refreshState: RefreshState.Idle,
        })
        storage.save({
            key:'recommendList',
            data: newList,
            expires: null
        })
    }
)
  • 附上项目Demo地址

参考

理解 JavaScript 的 async/await
async/await的基础用法

你可能感兴趣的:(React Native(四)数据本地存储)