美文网首页React Native实践React Native开发经验集React Native开发
React Native 在用户网络故障时自动调取缓存

React Native 在用户网络故障时自动调取缓存

作者: 92e6a2b361e8 | 来源:发表于2018-05-29 16:00 被阅读42次

    App往往都有缓存功能,例如常见的新闻类应用,如果你关闭网络,你上次打开App加载的数据还在,只是不能加载新的数据了。

    我的博客bougieblog.cn,欢迎前来尬聊。

    image

    集中处理请求

    如果你fetch数据的页面有多个,不集中处理的话每个页面都要单独进行缓存处理。那么,如何对http请求进行集中处理?
    在WebApp中常见的做法就是将请求放在action里面,例如VuexRedux。但是在业务逻辑较少的App中,我们往往可能不需要Redux。这时就需要我们自己对集中请求进行封装。

    封装AsyncStorage

    AsyncStorage只能存取字符串,我们需封装一下,让它能存取json:

    import { AsyncStorage } from 'react-native'
    
    class Storage {
        set({key, val}) {
            return AsyncStorage.setItem(key, JSON.stringify(val))
        }
        get(key) {
            return AsyncStorage.getItem(key).then(val => {
                return JSON.parse(val)
            })
        }
        remove(key) {
            return AsyncStorage.removeItem(key)
        }
        clear() {
            return AsyncStorage.clear()
        }
    }
    
    export default new Storage()
    

    命名为storage.js

    封装公共请求函数

    在网络故障时获取storage里的内容,网络良好时更新storage。

    import axios from 'axios'
    import storage from './storage'
    import apiList from './apiList'
    import {NetInfo, ToastAndroid} from 'react-native'
    /**
     * @param {String} api 接口名称
     * @param {Object} [replace={}] 替换url中的{}包裹的参数
     * @param {Object} [data={}] 传给服务端的数据
     * @param {Object} [headers={}] http请求头参数
     * @return {Promise} 返回promise
     */
    const $http = async ({api, replace, data, headers}) => {
        let regExp = /\{ *([\w_\-]+) *\}/g,
            url = apiList[api].url,
            replaceList = url.match(regExp)
        if(replaceList) {
            replaceList.forEach(i => {
                let key = i.slice(1, i.length - 1)
                url = url.replace(i, replace[key])
            })
        }
        let netStatu = await NetInfo.getConnectionInfo()
        let result
        if(['none', 'unknown'].includes(netStatu.type)) {
            ToastAndroid.show('请检查您的网络连接', ToastAndroid.SHORT)
            result = await storage.get(api) || null
        } else {
            try {
                let {data} = await axios({
                    method: apiList[api].method,
                    url: url,
                    data: data,
                    headers: headers
                })
                result = data
            } catch(err) {
                ToastAndroid.show(err.message, ToastAndroid.SHORT)
                result = await storage.get(api) || null
            }
            await storage.set({
                key: api,
                val: result
            })
        }
        return result
    }
    
    export default $http
    

    命名为service.js

    请求配置

    为标示请求唯一性,我们需给每个请求取一个名称:

    export default {
        GET_NEWS_LIST: {
            url: '/my/news?pageNum={pageNum}&pageSize={pageSize}',
            method: 'get'
        }
    }
    

    命名为apiList.js

    请求调用

    我们可以模仿一下VuexRedux的action:

    import $http from './service'
    
    export async function getNewsList(pageNum, pageSize) {
        return await $http({
            api: 'GET_NEWS_LIST',
            replace: {
                pageNum,
                pageSize
            }
        })
    }
    

    命名为serviceAction.js
    调用:

    import {getNewsList} from './serviceAction'
    
    // ...
    async componentDidMount() {
        let newsList = await getNewsList(1)
        this.setState({
            newsList
        })
    }
    // ...
    
    

    原文地址:React Native在用户网络故障时自动调取缓存

    相关文章

      网友评论

        本文标题:React Native 在用户网络故障时自动调取缓存

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