RN电商项目实战——2.组件的State

任何一个复杂的应用,都是由一个简单的应用发展而来的,当应用功能少的时候可能一个组件足够,但是随着功能的增加,把越来越多的功能放到一个组件中就不方便维护管理了。

组件中的数据

React Native 组件的数据分为两种,prop(属性 property的缩写) 和 state(状态) ,无论是属性还是状态的改变,都可能引发组件的重新渲染。 

所以,一定要记住一个原则,只能由属性或者状态控制界面显示内容的变化,其它的变量绝对不允许控制显示内容的变化。

归结为一个公式,就像下面这样:

UI=render(data)

公式的含义就是用户看到的界面(UI),应该是render()函数执行的结果,只接受数据(data)作为参数。这是一个毫无副作用的函数,data其实就是 prop 和 state ,两次函数如果输入的属性和状态相同,得到的 UI 一定是一样的。

prop 一般用于组件的对外接口,state 是组件的内部状态。

为了演示 prop 和 state 的使用,我们创建一个选择商品数量的组件。如下图所示: 

我们在工程目录下创建 src 目录,这个目录和 android 、ios 目录平级,用来存放 RN 源码,里面创建一个 component 文件夹用来存放自定义组件。

接下来自定义我们第一个组件 Counter ,工程文件路径:/src/component/Counter.js

组件中的 state

组件内部进行渲染主要由 state 控制,RN 中记录组件自身数据变化,必须用 state。

设计 Counter 组件显示内容如上“+” 和 “-” 按钮改变这个计数,这个变化的数据就要通过 state 控制。

初始化 state

通常在组件类的构造函数结尾处初始化 state,在 Counter 构造函数中,通过对 this.state 的赋值完成了对组件 state 的初始化,参考下面代码:

export default class Counter extends Component {
    // 构造
    constructor(props) {
        super(props);
        // 初始状态
        this.state = {
            value: 1
        };
    }
    // ...
}

搭建组件布局文件

组件分为左右各一个按钮,中间是一个输入框。实现代码参照下面代码片段:

参考上面代码片段,TouchableOpacity 控件按下时有高亮显示,是通用的处理按下效果的组件。

activeOpacity

属性是指的按下时的透明度,1 代表完全不透明

onPress

属性是按钮按下的事件

具体参考文档:

http://facebook.github.io/react-native/docs/touchableopacity.html

除了 TouchableOpacity 之外还有 TouchableNativeFeedback 类似组件比较常用,该遵循 Android 质感设计,体验比较好,只不过这个组件只适用于 Android 21版本以上。

有时候我们需要在 Android 21版本上使用 TouchableNativeFeedback,在 iOS 和 Android 低版本上使用 TouchableOpacity。你如果嫌麻烦,可以使用第三方组件 react-native-platform-touchable 地址:

https://github.com/react-community/react-native-platform-touchable

TouchableNativeFeedback 

TouchableNativeFeedback 只能包裹一个子组件,所以我们有时候为了替换方便,写 TouchableOpacity 时也只包裹一个子组件,所以写完了TouchableOpacity 然后在里面再定义一个相对多余的 View 当容器并不是什么坏习惯。比如前面的代码可以改成:

<TouchableOpacity activeOpacity={0.2}
                  onPress={this._reduce.bind(this)}>
     <View style={styles.reduce}>
          <Text allowFontScaling={false} style={[styles.btn1]}>-</Text>
      </View>
</TouchableOpacity>

文本控件 Text allowFontScaling={false} 表示不允许控件跟随手机字体大小变化。

TextInput 是输入框组件,

underlineColorAndroid=”transparent” 

是去掉 Android 系统中输入框的下划线。

我们再来看下样式代码,对照着上面代码,里面的组件样式在下面都定义了:

// 样式文件
const styles = StyleSheet.create({
    operatingBox: {
        width: 120,
        height: 35,
        borderColor: '#ddd', // 边框颜色
        borderWidth: 1,
        flexDirection: 'row',//横向布局
        alignItems: 'center',
        borderRadius: 5, //圆角半径
        overflow: 'hidden' // 超出控件范围的隐藏
    },
    btn1: {
        fontSize: 18,
        textAlign: 'center',
        backgroundColor: 'transparent'
    },
    inpBox: {
        flex: 1,
        borderRightWidth: 1,
        borderRightColor: '#ddd',
    },
    reduce: {
        width: 34,
        height: 34,
        justifyContent: 'center',
        borderRightWidth: 1,
        borderRightColor: '#ddd',
    },
    plus: {
        width: 34,
        height: 34,
        justifyContent: 'center'
    },
    inp1: {
        flex: 1,
        backgroundColor: 'transparent',
        textAlign: 'center', 
        padding: 0, 
        fontSize: 14
    },
});

读取和更新 state 变量

TextInput 组件中的 value 属性定义了输入框的内容,在这里用状态机变量控制显示, this.state.value.toString() 。

TouchableOpacity 组件通过 onPress 绑定了按钮的回调方法,onPress={this._reduce.bind(this)} 这里记得对方法进行绑定操作,否则在方法里无法使用 this 变量。

_reduce() 和 _plus() 方法分别通过 this.setState 函数修改了状态机变量的值。

在代码中,通过 this.state 可以读取到组件的当前 state 。值得注意的是,我们改变组件 state 必须要使用 this.setState 函数,而不能直接去修改 this.state。 当调用this.setState 函数才会驱动组件去更新,界面才会重新渲染。于是当我们点击 “+” 或者 “-” 的时候就可以看到界面的变化。

完善输入框

输入框也可以监听输入内容修改状态机变量,修改上面的代码:

   <TextInput style={styles.inp1}
              returnKeyType='done'
              maxLength={3}
              onEndEditing={this._checkNumber.bind(this)}
              value={this.state.value.toString()}
              keyboardType="numeric"
              onChangeText={(txt) => this.setState({value:Number(txt)})}
              autoFocus={false}
              underlineColorAndroid="transparent">
    </TextInput>
  • keyboardType 约束了软键盘类型,numeric 是数字类型键盘

  • returnKeyType 添加了完成的返回按钮

  • onChangeText 文本输入框变化的时候回调改方法,在这里修改了状态机变量

  • onEndEditing 输入完成的时候回调方法,调用了下面的 _checkNumber 方法。里面对输入内容做了处理,不允许 value 小于 1,并修改了状态机变量。

    _checkNumber(){
        let value=this.state.value;
        if(value===''||value<1){
            value=1;
        }else{
            value=Math.floor(value); //舍去小数
        }
        this.setState({value:value})
    }

虽然每次 setState 每次都刷新界面,大家不用考虑性能的问题,RN 框架都已经处理了。 查看性能方式:

  • Android模拟器 Ctrl/Command + M

  • iOS 模拟器 Command + D

调出调试菜单,点击 Show Perf Monitor, 如下图所示,当我们点击的时候并没有明显的影响性能,release版本比测试阶段性能消耗会进一步降低。

查看代码

参考React Native电商项目实战——开篇 示例代码可在 GitHub 上获取

https://github.com/yll2wcf/TShop

如果你已经从 GitHub 上克隆了这个程序的 Git 仓库,那么可以执行 git checkout 2a 签出程序的这个版本。 需要执行 npm install 或 yarn install

关注本公众号或者关注卓朗科技技术中心,回复RN 即可查看视频地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值