Mobx(二)實現(xiàn)選擇商品和小星星

效果圖展示

showmobx.gif

第一步,react-native init RN 創(chuàng)建一個新的項目。

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

npm install mobx --save

npm install mobx-react --save

第三步,導入babel組件,實現(xiàn)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 。

準備工作完成。現(xiàn)在寫入代碼。

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

把剛剛引入的組件導入進來,這里注意mobx-react/native需要加上/native,否則無法識別。

定義mobx結(jié)構(gòu)。
class CartItem {
    name="",  
    price = 0; //這里name 和 price 假設是從數(shù)據(jù)庫中取出
    
    @observable 
    count=0 ; //數(shù)目。 這里的數(shù)目是被觀察者,也就是每次觀察者需要監(jiān)視我的每個item 的count是否被改變。
    @observable
    isSelected = false; //是否被選擇,同樣需要觀察者查看,當前的item是否被選擇,如果選擇,做什么操作,如果不選擇做什么操作。
    
    @action   
    //這里的action,可以通過action來改變state,從而重新觸發(fā)渲染視圖的效果。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。如果不被選擇,那么當前的商品則數(shù)量是0。
     select = ()=>{

        this.isSelected = !this.isSelected;
        if(this.isSelected){
            ++this.count;
        }else{
            this.count = 0;
        }
    }
    
}
定義Cart 加入數(shù)據(jù)。
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這個類,在構(gòu)造函數(shù)里,初始化我們的數(shù)據(jù)。
同時,我們不難發(fā)現(xiàn)。這里的定義了一個被觀察者的items的數(shù)組,這個是數(shù)據(jù)源。也是用來觀察的。computed是通過計算得到值,在mobx里還有autorun,套用官方文檔的話來說:

如果你想響應式的產(chǎn)生一個可以被其它 observer 使用的值,請使用 @computed,如果你不想產(chǎn)生一個新值,而想要達到一個效果,請使用 autorun。 舉例來說,效果是像打印日志、發(fā)起網(wǎng)絡請求等這樣命令式的副作用。
以上都是被觀察者。我們不難發(fā)現(xiàn)。在mobx 的結(jié)構(gòu)中,定義的是被觀察者,在定義的數(shù)據(jù)源中,定義的也是被觀察者。接下來,我們做觀察者應該做的事,

渲染組件
我們定義個Item類。

Class Item extends Component{
//這里我們用到了小星星組件。在state定義小星星。
        constructor(props){
        super(props);
        this.state = {
            starCount: 0
        };
    }
    //處理小星星的方法。
      onStarRatingPress(rating) {
        this.setState({
            starCount: rating
        });
    }
    //渲染每個Item的內(nèi)容。
    render() {
        const { data } = this.props;
        //定義個data,在之后會調(diào)用這個組件,我們把需要用到的數(shù)據(jù)源放入就好。-->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>
    );
});

定義我們需要展現(xiàn)的類。而這個類作為展示者,他是一個觀察者。

@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}>


    {/*實現(xiàn)ListView的展示。*/}
                <ListView
                    dataSource={this.ds.cloneWithRows(this.cart.items.slice(0))}
                    renderRow={this.renderRow}

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

總結(jié):寫的不好,如果有錯誤,請及時的糾正。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,963評論 6 542
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,348評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,083評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,706評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,442評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,802評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,795評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,983評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,542評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,287評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,486評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,030評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,710評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,116評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,412評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,224評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,462評論 2 378

推薦閱讀更多精彩內(nèi)容

  • 無意中看到zhangwnag大佬分享的webpack教程感覺受益匪淺,特此分享以備自己日后查看,也希望更多的人看到...
    小小字符閱讀 8,218評論 7 35
  • 項目地址 從頭開始建立一個React App - 項目基本配置 npm init 生成 package.json ...
    瘦人假嚕嚕閱讀 89,565評論 33 78
  • 手機攝影 攝于2016年9月23日清早 愿每一份深情都不被辜負,每一個黎明都能迎來日出 最后祝每個人幸福快樂開森?...
    辣甜閱讀 282評論 0 0
  • I what:這個小片段告訴我們當我們面對新觀點和不同意見的時候,要采用“綠燈思維”,即要把我和我的觀點區(qū)分開,而...
    秦琴_3353閱讀 112評論 2 1
  • 2007年3月31日,天氣:陰。 重大事件:美麗鷺島舉行馬拉松,男女組的冠軍都是中國人,史無前例的第一次,之前舉辦...
    小貓吥吥妞閱讀 216評論 12 9