React Native之轻量级存储AsyncStorage

来源:互联网 发布:网络管理论坛 编辑:程序博客网 时间:2024/05/17 02:49

AsyncStorage是一个简单的、异步的、持久化的以键值对形式进行数据存储的存储系统,对于App来说是全局性的。它的作用等价于iOS的NSUserDefaluts或Android的SharedPreferences,使用AsyncStorage用来替换老旧的LocalStorage。

方法

它有很多方法,每一个方法都有回调函数,第一个参数是错误对象,错了就是展示错误信息,否则为null。都会返回一个Promise对象。

  • static getItem(key:string , callback:(error,result)):
    根据键来获取值,获取的结果会在回调函数中。
  • static setItem(key:string , value:string , callback:(error)): 设置键值对。
  • static removeItem(key:string , callback:(error)): 将根据键移出一项
  • static mergeItem:(key:string , value:string , callback:(error)):
    合并现有的值和输入值。
  • static clear(callback:(error)): 清除所有的项目。
  • static getAllKeys(callback:(error)): 获取所有的键。
  • static multiGet(keys,callback:(errors,result)):获取多项,其中keys是字符串数组。
  • static
    multiSet(keyValuePairs,callback:(errors)):设置多项,其中keyValuePairs是字符串的二维数组。
  • static multiRemove(keys,callback(errors)):删除多项,其中keys是字符串数组。
  • static multiMerge(keyValuePairs,callback:(errors)):多个键值合并,其中keyValuePairs是字符串中的二维数组。

示例

简单存储:

setData(text){    AsyncStorage.setItem(AsyncStorageKey,text,()=>{      this.setState({        data:text,      });    });  }

注意:可以设置一个回调,设置成功后,调用回调,修改状态机变量。

删除指定的KEY值

delData(){    // 读取key字段并将结果作为第二个参数传递给callback。  如果有任何错误发生,则会传递一个Error对象作为第一个参数。返回一个Promise对象。    AsyncStorage.getItem(AsyncStorageKey,(error,text)=>{      if(text=== null ){        alert(AsyncStorageKey +"没有对应的值");      }else{        //删除数据        AsyncStorage.removeItem(AsyncStorageKey,()=>{          this.setState({            data:"",          },()=>{            alert('删除成功');          });        });      }    });  }  

完整代码:

import React, { Component } from 'react';import {  StyleSheet,  View,  Text,  TouchableHighlight,  Dimensions,  AsyncStorage} from 'react-native';const {width, height} = Dimensions.get('window');var data = "";const AsyncStorageKey = "AS_";export default class AsyncStorageExample extends Component {  constructor(props) {    super(props);    this.state = {      data:""    };  }  setData(text){    AsyncStorage.setItem(AsyncStorageKey,text,()=>{      this.setState({        data:text,      });    });  }  delData(){    // 读取key字段并将结果作为第二个参数传递给callback。    // 如果有任何错误发生,则会传递一个Error对象作为第一个参数。返回一个Promise对象。    AsyncStorage.getItem(AsyncStorageKey,(error,text)=>{      if(text=== null ){        alert(AsyncStorageKey +"没有对应的值");      }else{        //删除数据        AsyncStorage.removeItem(AsyncStorageKey,()=>{          this.setState({            data:"",          },()=>{            alert('删除成功');          });        });      }    });  }  render() {    return (      <View style={styles.container}>          <TouchableHighlight style={styles.itemView} underlayColor="red" onPress={this.setData.bind(this,"我是小刀")}>              <Text style={styles.itemText}>                1、存储数据              </Text>          </TouchableHighlight>          <TouchableHighlight style={styles.itemView} underlayColor="red" onPress={this.delData.bind(this)}>              <Text style={styles.itemText}>                2、删除数据              </Text>          </TouchableHighlight>          <Text style={{paddingTop:40}}>            AsyncStorage存储的值是:{this.state.data}          </Text>      </View>    );  }}const styles = StyleSheet.create({  container: {    flex: 1,    backgroundColor: '#f2f2f2',    paddingTop:20,  },  itemView:{    backgroundColor:'grey',    height:44,    width:width,    justifyContent:'center',    marginTop:10,  },  itemText:{    fontSize:15,    color:'#ffffff',    textAlign:'left',    marginLeft:20,  },});

购物车结算示例

这里写图片描述
示例代码:

var React = require('react-native');var Dimensions = require('Dimensions');var {  AppRegistry,  StyleSheet,  Text,  View,  Image,  ScrollView,  WebView,  NavigatorIOS,  AsyncStorage,  TouchableOpacity,} = React;var Model = [    {        id: '1',        title:'商品1',        desc:'哎哟~不错哦',        price: 10000,        url:'http://ww4.sinaimg.cn/thumb180/4d7f0a6dgw1f18crfemfog20b405mqv7.gif'    },    {        id: '2',        title:'商品2',        desc:'哎哟~不错哦2',        price: 10330,        url:'http://ww3.sinaimg.cn/thumb180/6aa09e8fgw1f18abnz36mg20b30697wj.gif'    },    {        id: '3',        title:'商品3',        desc:'哎哟~不错3',        price: 100003,        url:'http://ww4.sinaimg.cn/thumb180/6298156bgw1f18ydrmj4cj20hi0bhq5r.jpg'    },    {        id: '4',        title:'商品4',        desc:'哎哟~不错哦4',        price: 100004,        url:'http://ww1.sinaimg.cn/thumb180/a5d15efdgw1f18k8pu0cyj20jg0jbdja.jpg'    },    {        id: '5',        title:'商品5',        desc:'哎哟~不错哦5',        price: 100005,        url:'http://ww2.sinaimg.cn/thumb180/005yYQOngw1f18lqh7hx9j326r1gincv.jpg'    },    {        id: '6',        title:'商品6',        desc:'哎哟~不错哦6',        price: 100006,        url:'http://ww2.sinaimg.cn/thumb180/5ba8d1cbgw1f18hhiaj3jj21kw1kw10x.jpg'    }];var styles = StyleSheet.create({    container : {        flex: 1    },    row : {        flexDirection: 'row',        marginBottom: 10,    },    item : {        flex: 1,        marginLeft:5,        borderWidth: 1,        borderColor: '#ddd',        marginRight: 5,        height: 100,    },    img: {        flex: 1,        backgroundColor: 'transparent',    },    item_text: {        backgroundColor: '#000',        opacity:0.7,        color:'#fff',        height:25,        lineHeight:18,        textAlign:'center',        marginTop:74    },    btn: {        backgroundColor: '#ff7200',        height: 33,        textAlign : 'center',        color: '#fff',        marginLeft:10,        marginRight: 10,        lineHeight: 24,        marginTop: 40,        fontSize: 18,    },    list_item : {        marginLeft: 5,        marginRight: 5,        padding:5 ,        borderWidth: 1,        height: 30,        borderRadius: 3,        borderColor: '#ddd',    },    list_item_desc : {        flex: 2,        fontSize: 15,    },    list_item_price: {        flex: 1,        textAlign: 'right',        fontSize: 15,    },    clear: {        marginTop : 10,        backgroundColor: '#fff',        color: '#000',        borderColor: '#ddd',        borderWidth:1,        marginLeft: 10,        marginRight:10,        lineHeight: 24,        height:33,        fontSize: 18,        textAlign: 'center',    }});//列表项组件var Item = React.createClass({    render:function(){        return(            <View style = {styles.item}>                <TouchableOpacity onPress = {this.props.press}>                    <Image                        resizeMode = 'contain'                        style = {styles.img}                        source = {{uri:this.props.url}}>                        <Text numberLines = {1} style = {styles.item_text}>                            {this.props.title}                        </Text>                    </Image>                </TouchableOpacity>            </View>            );    }});//列表组件var List = React.createClass({    getInitialState: function(){        return{            count: 0            };    },    componentDidMount: function() {        var _that = this;        AsyncStorage.getAllKeys(function(err,keys){            if (err) {                //TODO:存储取数据出错 ,给用户提示错误信息。            }            //将存储的商品条数反应到按钮上            _that.setState({                count:keys.length            });        });    },    render: function(){        var list = [];        for(var i in Model){            if (i % 2 ===0) {                var row = (                    <View style = {styles.row} key = {i}>                        <Item url={Model[i].url}                        title = {Model[i].title}                        press = {this.press.bind(this,Model[i])}></Item>                        <Item url = {Model[parseInt(i) + 1].url}                        title = {Model[parseInt(i) + 1].title}                        press = {this.press.bind(this,Model[parseInt(i) + 1])}></Item>                    </View>                );                list.push(row);            }        }        var counts = this.state.count;        var str = null;        if (counts) {            str = ',共'+counts+'件商品';        }        return(            <ScrollView style = {{marginTop:10}}>                {list}                <Text onPress = {this.goGouWu} style = {styles.btn}>                    去结算{str}                </Text>            </ScrollView>        );    },    //前往购物车方法    goGouWu: function(){        this.props.navigator.push({            component:GouWu,            title: '购物车'        });    },    //商品被选中方法    press: function(data){        var count = this.state.count;        count++;        //改变数字状态        this.setState({            count: count        });        //AsyncStorage 存储        AsyncStorage.setItem('SP-'+this.genId() + '-SP',JSON.stringify(data),function(err){            if (err) {                //TODO:存储出错            }        });    },    genId: function(){        return 'xxxxxxx-xxxx-2xxxx-bxxxxxxxxx'.replace(/[xy]/g,function(c){            var r = Math.random() * 16|0,            v = c == 'x'?r:(r & 0x3 | 0x8);            return v.toString(16);        }).toUpperCase();    }});var GouWu = React.createClass({    getInitialState:function(){        return{            data:[],            price:0        };    },    render:function(){        var data = this.state.data;        var price = this.state.price;        var list = [];        for(var i in data){            price += parseFloat(data[i].price);            list.push(                <View style = {[styles.row,styles.list_item]} key = {i}>                    <Text style = {styles.list_item_desc} >                        {data[i].title}                        {data[i].desc}                    </Text>                    <Text style = {styles.list_item_price} >${data[i].price}</Text>                </View>            );        }        var str = null;        if (price) {            str = ',共'+ price.toFixed(1)+'元'        }        return(            <ScrollView style = {{marginTop:10}}>                {list}                <Text style = {styles.btn} onPress = {this.paySuccess}>支付{str}</Text>                <Text style = {styles.clear} onPress = {this.clearStorage}>清空购物车</Text>            </ScrollView>        )    },    componentDidMount: function() {        var _that = this;        AsyncStorage.getAllKeys(function(err,keys){            if (err) {                //TODO:存储取数据出错                //如果发生错误,这里直接返回(return)防止进入下面的逻辑            }            AsyncStorage.multiGet(keys,function(errs,result){                //TODO:错误处理                //得到的结果是二维数组                //result[i][0]表示我们存储的键,result[i][1]表示我们存储的值                var arr = [];                for(var i in result){                    arr.push(JSON.parse(result[i][1]));                }                _that.setState({                    data:arr                });            });        })    },    clearStorage:function(){        var _that = this;        AsyncStorage.clear(function(err){            if (!err) {                _that.setState({                    data:[],                    price:0,                });                alert('购物车已经清空')            }            //TODO:err        });    },    paySuccess: function(){        var _that = this;        AsyncStorage.clear(function(err){            if (!err) {                alert("支付成功!")                _that.props.navigator.pop();            }            //TODO:err        });        _that.setState({                    data:[],                    price:0,                    count:0,                    str:'去结算'                });    }});var wxsPrj = React.createClass({  render: function() {    return (        <NavigatorIOS style = {styles.container}                      initialRoute = {                        {                            component:List,                            title:'商品列表',                        }                      }/>    );    }});AppRegistry.registerComponent('wxsPrj', () => wxsPrj);

代码说明:
首先我们来看一下模块, 我们创建Model(数据源) styles(样式列表) Item(列表项组件) List(列表组件) GouWu(购物车组件)
前三个没有什么好说的,先来说一下List组件:
在List组件中,我们用Model数据源来渲染列表项。使用i%2 ==0 来控制,每两个列表项目在一行中。
在press方法中我们让count+1,并且使用AsynStorage.setItem将选中的商品数据添加到App本地存储中。这里之所以使用SP-为前缀,-SP为后缀,采用GUID为存储的键名的一部分,是为了区分其他数据,好处:

可以缺粉用户数据,例如username信息。
可以放置key重复,保证同名商品都能被添加进购物车。
这样我们就把商品信息存储起来了。

我们在componentDidMount方法中作了一个处理,在用户第二次进入的时候,如果没有支付,依旧会告诉用户购物车中的商品数。使用Asy ncStorage.getAllKeys获取数据的条数,
在去结算按钮中,我们注册了点击方法goGouWu事件。使用this.props.navigator.push将购物车组件加载。

原创粉丝点击