react-nativeReact Native实践React Native开发经验集

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

2017-06-21  本文已影响200人  Kris_lee

效果图展示

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>
        );
        }
    }

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

上一篇下一篇

猜你喜欢

热点阅读