Mobx(二)实现选择商品和小星星

效果图展示

showmobx.gif

第一步,react-native init RN 创建一个新的项目。

第二步,导入mobx 和 mobx-react 。

npm install mobx --save

npm install mobx-react --save

第三步,导入babel组件,实现ES6修饰符的运用。

npm install babel-plugin-syntax-decorators --save
npm install babel-plugin-transform-decorators-legacy --save

第四步,.babelrc文件写入babel

    {
  "presets": ["react-native"],
  "plugins": [
    "syntax-decorators",
    "transform-decorators-legacy"
  ]
}

第五补,小星星组件的导入

"react-native-star-rating": "^1.0.7",
"react-native-vector-icons": "^4.2.0",
"react-native-button": "^2.0.0",

小星星组件需要导入这三个必要的组件,其中 react-native-vector-icons需要react-native link react-native-vector-icons 。

准备工作完成。现在写入代码。

import { observable, action, computed } from 'mobx';
import { observer } from 'mobx-react/native';
import StarRating from 'react-native-star-rating';

把刚刚引入的组件导入进来,这里注意mobx-react/native需要加上/native,否则无法识别。

定义mobx结构。
class CartItem {
    name="",  
    price = 0; //这里name 和 price 假设是从数据库中取出
    
    @observable 
    count=0 ; //数目。 这里的数目是被观察者,也就是每次观察者需要监视我的每个item 的count是否被改变。
    @observable
    isSelected = false; //是否被选择,同样需要观察者查看,当前的item是否被选择,如果选择,做什么操作,如果不选择做什么操作。
    
    @action   
    //这里的action,可以通过action来改变state,从而重新触发渲染视图的效果。inc是增加。如果点击增加,那么说明当前item是被选择的
    inc = () =>{
        ++this.count;
        this.isSelected = true; 
    }
    
     @action
     //同理这里dec也是减少的操作。
    dec = ()=>{
        if(this.count >1){
            --this.count;


        }else {
            this.count = 0;
            this.isSelected = false;
        }

    }
    
    @action
    //是否被选择的action。如果不被选择,那么当前的商品则数量是0。
     select = ()=>{

        this.isSelected = !this.isSelected;
        if(this.isSelected){
            ++this.count;
        }else{
            this.count = 0;
        }
    }
    
}
定义Cart 加入数据。
class Cart{

    @observable
    items = [];

    constructor(){
        for (let i = 0; i < 150; i++) {
            this.items.push(new CartItem(
                `商品${i}`,
                Math.floor(Math.random() * 100000)/100,
            ));
        }
    }
//通过计算得到的值。
    @computed
    get count(){
        return this.items.reduce((a,b)=>a+b.count, 0);
    }

    @computed
    get price(){

        return this.items.reduce((a,b)=>a + (b.price * b.count),0);
    }



}

这里我们定义Cart这个类,在构造函数里,初始化我们的数据。
同时,我们不难发现。这里的定义了一个被观察者的items的数组,这个是数据源。也是用来观察的。computed是通过计算得到值,在mobx里还有autorun,套用官方文档的话来说:

如果你想响应式的产生一个可以被其它 observer 使用的值,请使用 @computed,如果你不想产生一个新值,而想要达到一个效果,请使用 autorun。 举例来说,效果是像打印日志、发起网络请求等这样命令式的副作用。
以上都是被观察者。我们不难发现。在mobx 的结构中,定义的是被观察者,在定义的数据源中,定义的也是被观察者。接下来,我们做观察者应该做的事,

渲染组件
我们定义个Item类。

Class Item extends Component{
//这里我们用到了小星星组件。在state定义小星星。
        constructor(props){
        super(props);
        this.state = {
            starCount: 0
        };
    }
    //处理小星星的方法。
      onStarRatingPress(rating) {
        this.setState({
            starCount: rating
        });
    }
    //渲染每个Item的内容。
    render() {
        const { data } = this.props;
        //定义个data,在之后会调用这个组件,我们把需要用到的数据源放入就好。-->const data = this.props.data.

        return (
{/*给每个Item添加一个点击事件,用来判断是否被选择*/}
            <TouchableOpacity onPress = {data.select}>
                <View>

                <View style={styles.item}>
                {/*是否被选择,展示不同的页面效果*/}
                    <Text  style = {data.isSelected ? styles.istrue :styles.isfalse}>{data.name}</Text>
                    <Text style={styles.price}>${data.price}</Text>
                    {/*加号的方法*/}
                    <Text style={styles.btn} onPress={data.inc}>+</Text>
                    <Text>{data.count}</Text>
                    {/*减号的方法*/}
                    <Text style={styles.btn} onPress={data.dec}>-</Text>

                </View>
                {/*渲染小星星的组件*/}
                    <View>
                        <StarRating
                            disabled={false}
                            maxStars={5}
                            rating={this.state.starCount}
                            selectedStar={(rating) => this.onStarRatingPress(rating)}
                        />
                    </View>

                </View>
            </TouchableOpacity>
        )

    }
}

定义一个Info用来观察count和price

const Info = observer(function({cart}) {
    return (
        <Text>
            Count: {`${cart.count}`} {'\n'}
            Price: {cart.price.toFixed(2)} {'\n'}
        </Text>
    );
});

定义我们需要展现的类。而这个类作为展示者,他是一个观察者。

@observer
export default class MobxDemo extends Component {
实例化Cart 。
    cart = new Cart();
  //  CartItem = new CartItem();
//定义ListView.DataSource
    ds = new ListView.DataSource({
        rowHasChanged: (v1, v2) => v1 !== v2,
    });
//渲染组件renderRow
    renderRow = (data) => {
        return (
            <Item data={data}/>
        );
    };

    //返回
    render() {
        //const { data } = this.props;
        return (
            <View style={styles.container}>


    {/*实现ListView的展示。*/}
                <ListView
                    dataSource={this.ds.cloneWithRows(this.cart.items.slice(0))}
                    renderRow={this.renderRow}

                />
                <Info cart={this.cart}/>
            </View>
        );
        }
    }

总结:写的不好,如果有错误,请及时的纠正。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342

推荐阅读更多精彩内容

  • 无意中看到zhangwnag大佬分享的webpack教程感觉受益匪浅,特此分享以备自己日后查看,也希望更多的人看到...
    小小字符阅读 8,133评论 7 35
  • 项目地址 从头开始建立一个React App - 项目基本配置 npm init 生成 package.json ...
    瘦人假噜噜阅读 89,485评论 33 78
  • 手机摄影 摄于2016年9月23日清早 愿每一份深情都不被辜负,每一个黎明都能迎来日出 最后祝每个人幸福快乐开森ฅ...
    辣甜阅读 266评论 0 0
  • I what:这个小片段告诉我们当我们面对新观点和不同意见的时候,要采用“绿灯思维”,即要把我和我的观点区分开,而...
    秦琴_3353阅读 108评论 2 1
  • 2007年3月31日,天气:阴。 重大事件:美丽鹭岛举行马拉松,男女组的冠军都是中国人,史无前例的第一次,之前举办...
    小猫吥吥妞阅读 203评论 12 9