React Native(四)数据本地存储

作者: 二木又土 | 来源:发表于2017-10-10 15:43 被阅读5113次

    本地数据存储指的是将数据存储在设备中,在需要数据的时候调用,数据并不会因为应用退出,或者网络断开而无法获取。在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
            })
        }
    )
    

    参考

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

    相关文章

      网友评论

        本文标题:React Native(四)数据本地存储

        本文链接:https://www.haomeiwen.com/subject/nflvyxtx.html