RN演示类似购物车清空的功能, 异步存储AsyncStorage

由Navigator跳转到本界面,实现点击添加商品信息,异步存储点击确定按钮跳转到结算界面,实现添加商品的数据读取与界面展示,并实现点击清空按钮,清空当前页面的数据,返回到上一界面与数据的初始化!

Navigator跳转到的当前界面:

import React, {
    Component,
} from 'react';

import {
    StyleSheet,
    Text,
    AppRegistry,
    Dimensions,
    View,
    AsyncStorage,
    ScrollView,
    Image
} from 'react-native';

import Item from './Item';
import GouWu from './GouWu';



const Model = [
    {
        id: '1',
        title: '猕猴桃1',
        desc: '12个装',
        price: 99,
        url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg',
    },
    {
        id: '2',
        title: '牛油果2',
        desc: '6个装',
        price: 59,
        url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg',
    },
    {
        id: '3',
        title: '猕猴桃3',
        desc: '3个装',
        price: 993,
        url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg',
    },
    {
        id: '4',
        title: '猕猴桃4',
        desc: '4个装',
        price: 994,
        url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg',
    },
    {
        id: '5',
        title: '猕猴桃5',
        desc: '5个装',
        price: 995,
        url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg',
    },
    {
        id: '6',
        title: '猕猴桃6',
        desc: '6个装',
        price: 996,
        url: 'http://image18-c.poco.cn/mypoco/myphoto/20160610/18/17351665220160610181307073.jpg',
    },
];

export default class AwesomeProject extends Component {
    constructor(props) {
        super(props);
        this.state = {
            count: 0,
        };
    }

    componentDidMount() {
        let _that = this;
        AsyncStorage.getAllKeys(
            function (err, keys) {
                if (err) {
                    //TODO:存储取数据出错
                    //给用户提示错误信息
                    console.log(err);
                } else {
                    console.log('读取成功了的个数:'+keys.toString());
                }
                _that.setState({

                    count: keys.length,
                });
            }
        );
    }

    render() {
        let list = [];
        for (let i in Model) {
            if (i % 2 === 0) {
                //两个等号 :不判断类型
                //三个等号:判断类型
                let row = (
                    <View style={styles.row} key={i}>
                        <Item
                            {...this.props}
                            title={Model[i].title}
                            url={Model[i].url}
                            press={()=>{
                                this.press(Model[i])
                            }}
                        />

                        <Item
                            {...this.props}
                            title={Model[parseInt(i) + 1].title}
                            url={Model[parseInt(i) + 1].url}
                            press={() =>{
                                   this.press(Model[parseInt(i) + 1])
                              } }
                        />
                    </View>
                );
                list.push(row);
            }
        }
        let count = this.state.count;
        let str = null;
        if (count > 0) {
            str = ',共' + count + '件商品';
        }
        return (
            <ScrollView style={{ marginTop: 10 }}>
                {list}
                <Text onPress={this.goGouWu.bind(this) } style={styles.btn}>去结算{str}</Text>
            </ScrollView>
        );
    }

    goGouWu() {
        //alert('点击了去购物车');
        const { navigator } = this.props;
        //为什么这里可以取得 props.navigator?请看上文:
        //<Component {...route.params} navigator={navigator} />
        //这里传递了navigator作为props
        if (navigator) {
            navigator.push({
                component: GouWu,
                name: 'GouWu',
                params:    {
                    callBack:()=>{
                        this.setState({count:0})
                    }
                }
            })
        }
    }

    press(data) {
        this.setState({
            count: this.state.count + 1,
        });
        //AsyncStorage异步存储
        AsyncStorage.setItem('SP-' + this.genId() + '-SP', JSON.stringify(data), function (err) {
            if (err) {
                //TODO:存储出错
                alert(err);
            } else {
                // alert('保存成功');
            }
        });
    }

    //生成随机ID:GUID 全局唯一标识符(GUID,Globally Unique Identifier)是一种由算法生成的二进制长度为128位的数字标识符
    //GUID生成的代码来自于Stoyan Stefanov
    genId() {
        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
            let r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
            return v.toString(16);
        }).toUpperCase();
    }
}

Item.js

import React, {Component} from 'react';

import{
    AppRegistry,
    StyleSheet,
    View,
    TouchableOpacity,
    Image,
    Text,
    Dimensions
} from 'react-native';

const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;

export  default class Item extends Component {
     // constructor(props){
     //     super(props);
     //     this.state={
     //         url: 'https://gss0.bdstatic.com/5eR1dDebRNRTm2_p8IuM_a/res/img/richanglogo168_24.png',
     //         title: '默认标题',
     //     }
     // }
    static defaultProps = {
        url: 'https://gss0.bdstatic.com/5eR1dDebRNRTm2_p8IuM_a/res/img/richanglogo168_24.png',
        title: '默认标题',
    };  // 注意这里有分号
    static propTypes = {
        // ...View.propTypes,
        url: React.PropTypes.string.isRequired,
        title: React.PropTypes.string.isRequired,
        // press: React.PropTypes.func.isRequired,
    };  // 注意这里有分号


    render() {
        console.log(this.props.url + '....'+ this.props.title)
            {/*<View style={styles.item}>*/}
        return (
                <TouchableOpacity
                    style={styles.item}
                     onPress={() =>{
                         this.press();
                     }}
                    // onPress={this.props.press}
                >
                    <Image resizeMode='contain'
                           style={styles.img}
                           source={{ uri: this.props.url}}
                    >

                        <Text numberOfLines={1} style={styles.item_text}>{this.props.title}</Text>

                    </Image>
                </TouchableOpacity>
            // </View>
        );
    }
    press(){
        this.props.press();
    }
}

Gouwu.js

import React, {Component} from 'react';
import{
    AppRegistry,
    StyleSheet,
    View,
    Text,
    ScrollView,
    AsyncStorage
} from 'react-native';

export  default class GouWu extends Component {
    constructor(props) {
        super(props);
        this.state = {
            price: 0,
            data: [],
        };
    }
    render() {
        //第二次render的时候 data不为空了
        let data = this.state.data;
        let price = this.state.price;
        let list = [];
        for (let 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>
            );
        }
        let str = null;
        if (price) {
            str = ',共' + price.toFixed(2) + '元';
        }
        return (
            <ScrollView style={{ marginTop: 10 }}>
                {list}
                <Text style={styles.btn}>支付{str}</Text>
                <Text style={styles.clear} onPress={()=>this.clearStorage() }>清空购物车</Text>
            </ScrollView>
        );
    }
    componentDidMount() {
        let _that = this;
        AsyncStorage.getAllKeys(
            function (err, keys) {
                if (err) {
                    //TODO 存储数据出错
                    //return ;
                }
                //keys是字符串数组
                AsyncStorage.multiGet(keys, function (err, result) {
                    //得到的结构是二维数组
                    //result[i][0]表示我们存储的键   result[i][1]表示我们存储的值
                    let arr = [];
                    for (let i in result) {
                        arr.push(JSON.parse(result[i][1]));
                    }
                    _that.setState(
                        { data: arr, }
                    );


                });
            }
        );
    }

    clearStorage() {
        const { navigator } = this.props;
        let _that = this;
        //开了一个线程
        AsyncStorage.clear(function (err) {
            if (!err) {
                _that.setState({
                    data: [],
                    price: 0,
                });
                _that.props.callBack() ;
                navigator.pop();
                alert('购物车已经清空');
            }
        });
    }
}

在GouWu.js中如果不定义let _that = this;而是直接调用// this.props.callBack() ; //开了一个线程,采用this会报错,找不到this,需要在线程外定义this。

简单的上传几张图片,看下效果:
默认的首页图片
这里写图片描述
第一张,选中了4种商品,去结算,选中的商品数据:
这里写图片描述
若不选择任何一种商品,直接跳转到结算界面的默认显示效果
这里写图片描述
第二张,跳转到结算界面,读取存储的数据,显示到界面上
这里写图片描述
第三张,点击清空按钮,清楚当前界面的数据,并返回到上一界面,清空数据
这里写图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值