【呆萌の学习】分析一个“简单”的项目来学习react-native

前端之家收集整理的这篇文章主要介绍了【呆萌の学习】分析一个“简单”的项目来学习react-native前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

前言

突发情况,不得不快速入门学习react-native?,
文章比较倾向于帮助我自己?疏通思维的。
我先贴出学习的项目地址:https://github.com/shooterRao...
是一个比较简洁的水果商城,作者大大也写了文章在掘金:https://juejin.im/post/5a3f06...
但是作为小白来说,其中有很多细节值得学习和研究。

结构

新建src文件夹来存放页面内容和素材。
src下分为:common(公用组件)、img、mobx、scene(页面)四个文件夹。
因为每个页面下可能又有几个组件可以抽出来,所以都各自创建了文件夹来分开来。

Root.js

作用:用于react-navigation的配置。

react-navigation
原本react-native是有默认的Navigator组件,但是在新版本中已经废除了,现在就主要都用这个模块来实现导航。
官方文档:https://reactnavigation.org/d...
博客翻译:http://blog.csdn.net/u0137181...

StackNavigator:用来@R_662_404@面和传递参数
TabNavigator:类似底部导航栏,用来在同一屏幕下切换不同界面
DrawerNavigator:侧滑菜单导航栏,用于轻松设置带抽屉导航的屏幕

这里要实现首页底部菜单,实现菜单内的页面之间的跳转,要用TabNavigator,
而因为我们也要实现大版权之间的@R_662_404@面,所以也要引入StackNavigator。
另外,我们还要引入所有的主页面

import TabBarItem from './common/tabBarItem' 
import theme from './common/color'

这里还引入了tabBarItem和color,
tabBarItem的主要内容如下:

const TabBarItem = ({focused,tintColor,selectedImage,normalImage}) => {
    return (
        <Image
            source = {focused ? selectedImage : normalImage}
            style={{ tintColor: tintColor,width: 25,height: 25 }}
        />
    )
}

返回的是导航图标被选中和没被选中的一些改变设定,用于tabBarIcon自定义的设置。
color.js里面保存的就是颜色的常量值,单独抽出来方便使用和修改
然后定义TabNavigator常量,格式按照文档模仿写即可。再定义一个StackNavigator来绑定TabNavigator实现页面跳转,随后返回这个StackNavigator。

common/viewpager

ViewPager是一种滚动功能,也就是首页的轮播图了,这里的代码应该是直接引用过来的。
这里有一些不太熟悉的模块~
create-react-class:很明显,有了它可以使用React.createClass

prop-types:对react组件中props对象中的变量进行类型检测(老版中直接可以从react里面引入PropTypes,后面独立出来成为了模块)。

react-timer-mixinhttps://www.npmjs.com/package...
避免setTimeout,setInterval等带来的潜在风险,用于计时的模块。

不熟悉的react-native组件/API:
Dimensionshttps://reactnative.cn/docs/0...
本模块用于获取设备屏幕的宽高。

TouchableOpacityhttps://reactnative.cn/docs/0...
当按下的时候,封装的视图的不透明度会降低。

mobx

mobx官网:http://cn.mobx.js.org/
mobx一个功能强大,上手容易的状态管理工具,这里使用它来保存数据进行切换。
参考文章https://www.jianshu.com/p/505...
在这个项目里,cartGoods.js、newGoods.js、categoryGoods.js分别暂存了商城的数据,通过store.js来管理。

observable,顾名思义,用于观察一个对象,当对象变化的时候,如果对象在autorun()中,就会执行对应的动作。
如果不是观测每一个变化,也可以用computed,顾名思义,可以用于计算:

const plus = computed(() => number.get() > 0);

会返回true或者false,改变的时候,对象在autorun()中且结果变化才会执行。

mobx推荐将修改被观测变量的行为放在action中

项目中使用了ES7语法,所以要安装模块transform-decorators-legacy
然后定义对应的数据处理的动作,返回RootStore这个类。

scene/Home

主页拥有一个轮播图,以及新品水果的呈现,所以肯定要引入轮播组件和新品水果的数据。
HomeScreen.js:
为了获得mobx的数据,引入Provider才能获取到。加上@inject('rootStore'),可以使用 this.props.rootStore来获取数据。

@inject('rootStore')来实现数据的获取,然后再一步步地把数据传到它们的子组件中。

再来看主类中的内容

static navigationOptions = {
        title: '迷你水果商城',headerTitleStyle: {alignSelf: 'center',fontSize: 15,color: theme.fontColor},headerStyle: {height: 38,backgroundColor: theme.color}
};

定义了页面头部的信息的样式内容,也是react-navigation中的(这里留个疑问,它怎么定位到头顶的,我如果想定位到其他地方要怎么改呢)。
构造函数中,初始化轮播图片链接地址
然后渲染页面内容

NewGoodsItem.js
这里是封装了展示最近新品的单个小块:

const NewGoodsItem = ({name,price,image,onPress}) => {
    return (
        <TouchableOpacity onPress={() => onPress && onPress()}>
        <View style={styles.item}>
            <Image source={image} style={styles.image}/>
            <Text>{name}</Text>
            <Text>¥ {price}/500g</Text>
        </View>
        </TouchableOpacity>
    )
}

代码看得出,你点击每个小块的时候,还会有一个透明度的变化。
NewGoodsView.js
是整个新品的板块
在HomeScreen.js中是这样写的:

<NewGoodsView itemDatas={data} navigation={this.props.navigation}/>

传入水果数据和导航给NewsGoodsView,这里this.props.navigation是react-navigation中带的:

在界面组件注入到StackNavigator中时,界面组件就被赋予了navigation属性,即在界面组件中可以通过【this.props.navigation】获取并进行一些操作。

在NewGoodsView相应写的是:

<NewGoodsItem onPress={()=> props.navigation.navigate('ItemDetail',{value})} name={value.name} price={value.price} image={value.image} key={index}/>

能想到意思是,当点下新品的单个项目,页面导航会跳转到水果细则。
另外,就是使用了map循环去把整个列表都列出来。

scene/Category

分类页面

这个页面有一个子导航,以及下面对应的商品列表。
CategoryScreen.js
为了实现子导航,引入了react-native-scrollable-tab-view这个模块:
https://www.jianshu.com/p/b77...

CategoryListView.js
每个分类页面内容封装,有一个可以重新刷新的操作,如果数据有变化再打乱渲染。
就引用了refreshControl控件,用于下拉刷新:https://reactnative.cn/docs/0...

scene/ItemDetail

这里引用了一个react-native-easy-toast模块:https://github.com/crazycodeb...

toast是“吐司”的意思,它属于android杂项组件,是一个简单的消息提示框,类似于javascript中的alert

商品信息页面,除了水果的信息之外,还有一个加入购物车的操作。
在构造函数中定义了一个bounceValue: new Animated.Value(1),用于动画变化,可以查看文档:
https://reactnative.cn/docs/0...
后面在添加到购物车的时候,使用了:

this.state.bounceValue.setValue(1.5);
        Animated.spring(                         
            this.state.bounceValue,toValue: 1,friction: 1,}
          ).start();

实现了购车图标蹭的一下变大又弹回去的动画。

MessageView.js:
底部的商品详情/产品参数/售后保障,也用到了之前说的react-native-scrollable-tab-view这个模块。
因为内容比较简单,没有像之前一样再把tab下的子模块又抽出来,直接定义了一个结构来引用:

const List = ({ message }) => (
    <View style={{ flex: 1 }}>
        <Text>{message}</Text>
    </View>
)

scene/Cart

CartScreen.js
可以直接导航到购物车页面,也可以在商品的页面跳转到购物车页面,在商品详细页面跳转的时候传入了一个参数headerStyle,由此判断进入方式是哪种,好显示返回箭头。
@computed get dataSource() 根据数据是否变化来更新商品数组内容
_renderItem((item}) 根据数据渲染商品
_keyExtractor(item,index) 返回目标商品的名字
(FlatList的keyExtractor属性指定使用id作为列表每一项的key)

CartList.js
商品列表,要检测商品选择/不选的变化,检测商品选择数目的变化(+/-)。

CartCheckOut.js
使用了Alert API:https://reactnative.cn/docs/0...

以及react-native-loading-spinner-overlay模块:https://www.npmjs.com/package...
用于加载时的动画显示提示

<Spinner visible={this.state.visible} textContent={this.state.loadText} textStyle={{fontSize: 15,color: '#FFF'}} />

等支付的时候才显示这个控件。
支付完成后,需要拷贝购物车数据到订单数据中,购物车数据清空。

scene/Order & scene/Mine

Order的情况类比原来几个页面,简单的数据获取就可以了。Mine里是比较普通的页面,不仔细探究了。

猜你在找的React相关文章