ReactNative自定义组件

2024-08-24 08:48

本文主要是介绍ReactNative自定义组件,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • ReactNative自定义组件
    • 组件
    • 例子
      • 标题组件
      • LinearLayout组件
    • 性能优化
      • 渲染优化

ReactNative系列-文章

ReactNative自定义组件

组件

一个ReactNative的APP界面其实是各种组件的组合,但是官方给我们提供的组件或许在样式或功能上不能满足实际的需求,所以在开发过程中,我们不可避免的需要写一些新的组件以满足项目需求。那么,它的自定义组件会有什么类型区别呢?例如说,这个组件的主要作用是“部件(widget)”还是“布局(layout)”。本人从ReactNative自定义组件上的思考多数来自于安卓的自定义控件思想。

以安卓的自定义控件为例,安卓上的自定义控件主要是继承View或ViewGroup来具体实现,前者的作用主要是提供部件(widget)的功能,后者主要是提供布局(layout)的功能。再举个例子,我们可能需要针对具体样式去实现一个标题栏,这个标题栏不需要作为容器去承载其它的控件,它仅仅只是一个最基本的标题view,所以它主要是提供部件(widget)的功能。

而ReactNative中的自定义组件,假设从功能属性大致也可以区分为widget和layout,那么我们在编写组件的时候,主要的区别即是在于this.props.children。当然,React的核心思想还是component组件,这个分类仅在于我的理解。如果不了解this.props.children,可以去看我的这篇props详解。

一个ReactNative自定义组件基本流程如下:

  1. 继承Component或PureComponent实现render()方法。
  2. 定义组件属性字段及其类型,以及是否必须,如不必须则默认字段值是什么。
  3. 绑定点击或者触摸等事件方法,执行前需要判空。

例子

标题组件

以一个标题组件为例,它主要功能是部件(widget),所以我们不需要去定义this.props.children。

模拟器使用安卓。

import React from 'react';
import { View, StatusBar, Image, Text, TouchableOpacity, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';export default class Title extends React.Component {static propTypes = {title: PropTypes.string,onBackPress: PropTypes.func,onMenuPress: PropTypes.func}// 定义属性字段的默认值static defaultProps = {title: '',onBackPress: undefined,onMenuPress: undefined}constructor(props) {super(props);// 左边:创建了this.backPress变量。右边:创建一个与backPress()相同的函数,它将绑定到这个组件,然后赋值给this.backPress变量this.backPress = this.backPress.bind(this); this.menuPress = this.menuPress.bind(this);}backPress() {if(this.props.onBackPress) {// 判断属性onBackPress是否传入函数,传了就执行它this.props.onBackPress();}}menuPress() {if(this.props.onMenuPress) {this.props.onMenuPress();}}render() {return(<View style={styles.container}><StatusBar backgroundColor="#008577" barStyle="light-content"/><TouchableOpacity style={styles.back}onPress={this.backPress}><Image source={require('../../static/images/back.png')}style={{marginStart: 12}}/></TouchableOpacity><Text style={styles.title}>{this.props.title}</Text><TouchableOpacity style={styles.menu}onPress={this.menuPress}><Image source={require('../../static/images/menu.png')}style={{marginEnd: 12}}/></TouchableOpacity></View>)}
}const styles = StyleSheet.create({container: {flexDirection: 'row',alignItems: 'center',backgroundColor: '#008577',height: 50},back: {justifyContent: 'center',alignItems: 'flex-start',height: 50,width: 50},title: {flexGrow: 1,textAlign: 'center',color: '#ffffff',fontSize: 18},menu: {justifyContent: 'center',alignItems: 'flex-end',height: 50,width: 50}
})

具体解释请看注释。在其它组件中对于该组件的调用:

<Title title="标题"onBackPress={()=>{ToastAndroid.show('back', ToastAndroid.SHORT);}}onMenuPress={()=>{ToastAndroid.show('menu', ToastAndroid.SHORT);}}/>

演示:

LinearLayout组件

前一个例子不需要去定义this.props.children,而LinearLayout组件是模仿安卓原生平台的LinearLayout,它的主要功能是布局layout,所以这是它们两者之间最大的区别。这里的LinearLayout组件当然没有安卓原生那么完备,仅简单示例。

import React, { Component } from 'react';
import { View, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';export default class LinearLayout extends Component {static propTypes = {orientation: PropTypes.string,gravity: PropTypes.string,}static defaultProps = {orientation: 'vertical',gravity: undefined,}render() {return(<View style={{flexDirection: (this.props.orientation === 'horizontal') ? 'row' : 'column'}}>{this.props.children}</View>)}
}

其它组件对于该组件的调用:

import React, { Component } from 'react';
import { View, ToastAndroid, Button, Text } from 'react-native';
import Title from './Title';
import LinearLayout from './LinearLayout';export default class App extends Component {constructor(props) {super(props);this.state = {orientation: 'vertical'}}render() {return (<View style={{ flexDirection: 'column', flex: 1 }}><Titletitle='标题'onBackPress={() => {ToastAndroid.show('back', ToastAndroid.SHORT);}}onMenuPress={() => {ToastAndroid.show('menu', ToastAndroid.SHORT);}} /><Button title='切换' onPress={() => {if (this.state.orientation === 'vertical') {this.setState({orientation: 'horizontal'})} else {this.setState({orientation: 'vertical'})}}} /><LinearLayout orientation={this.state.orientation}><Text>1</Text><Text>2</Text><Text>3</Text></LinearLayout></View>);}
}

演示:

性能优化

渲染优化

渲染优化在这里主要还是针对组件树的渲染,我们可以有两种办法来实现,二选一:1. 继承PureComponent实现组件;2. 实现shouldComponentUpdate()方法。不了解看以看我的这两篇:Component与PureComponent的区别/ shouldComponentUpdate机制。

更多的请查看这里ReactNative性能优化总结。

这篇关于ReactNative自定义组件的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1102006

相关文章

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

如何自定义一个log适配器starter

《如何自定义一个log适配器starter》:本文主要介绍如何自定义一个log适配器starter的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求Starter 项目目录结构pom.XML 配置LogInitializer实现MDCInterceptor

Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析

《Spring组件实例化扩展点之InstantiationAwareBeanPostProcessor使用场景解析》InstantiationAwareBeanPostProcessor是Spring... 目录一、什么是InstantiationAwareBeanPostProcessor?二、核心方法解

Druid连接池实现自定义数据库密码加解密功能

《Druid连接池实现自定义数据库密码加解密功能》在现代应用开发中,数据安全是至关重要的,本文将介绍如何在​​Druid​​连接池中实现自定义的数据库密码加解密功能,有需要的小伙伴可以参考一下... 目录1. 环境准备2. 密码加密算法的选择3. 自定义 ​​DruidDataSource​​ 的密码解密3

C++ RabbitMq消息队列组件详解

《C++RabbitMq消息队列组件详解》:本文主要介绍C++RabbitMq消息队列组件的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. RabbitMq介绍2. 安装RabbitMQ3. 安装 RabbitMQ 的 C++客户端库4. A

spring-gateway filters添加自定义过滤器实现流程分析(可插拔)

《spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔)》:本文主要介绍spring-gatewayfilters添加自定义过滤器实现流程分析(可插拔),本文通过实例图... 目录需求背景需求拆解设计流程及作用域逻辑处理代码逻辑需求背景公司要求,通过公司网络代理访问的请求需要做请

PyQt6中QMainWindow组件的使用详解

《PyQt6中QMainWindow组件的使用详解》QMainWindow是PyQt6中用于构建桌面应用程序的基础组件,本文主要介绍了PyQt6中QMainWindow组件的使用,具有一定的参考价值,... 目录1. QMainWindow 组php件概述2. 使用 QMainWindow3. QMainW

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依