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将购物车组件加载。