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

相关文章

CSS自定义浏览器滚动条样式完整代码

《CSS自定义浏览器滚动条样式完整代码》:本文主要介绍了如何使用CSS自定义浏览器滚动条的样式,包括隐藏滚动条的角落、设置滚动条的基本样式、轨道样式和滑块样式,并提供了完整的CSS代码示例,通过这些技巧,你可以为你的网站添加个性化的滚动条样式,从而提升用户体验,详细内容请阅读本文,希望能对你有所帮助...

四种Flutter子页面向父组件传递数据的方法介绍

《四种Flutter子页面向父组件传递数据的方法介绍》在Flutter中,如果父组件需要调用子组件的方法,可以通过常用的四种方式实现,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录方法 1:使用 GlobalKey 和 State 调用子组件方法方法 2:通过回调函数(Callb

Vue项目中Element UI组件未注册的问题原因及解决方法

《Vue项目中ElementUI组件未注册的问题原因及解决方法》在Vue项目中使用ElementUI组件库时,开发者可能会遇到一些常见问题,例如组件未正确注册导致的警告或错误,本文将详细探讨这些问题... 目录引言一、问题背景1.1 错误信息分析1.2 问题原因二、解决方法2.1 全局引入 Element

vue解决子组件样式覆盖问题scoped deep

《vue解决子组件样式覆盖问题scopeddeep》文章主要介绍了在Vue项目中处理全局样式和局部样式的方法,包括使用scoped属性和深度选择器(/deep/)来覆盖子组件的样式,作者建议所有组件... 目录前言scoped分析deep分析使用总结所有组件必须加scoped父组件覆盖子组件使用deep前言

基于Qt Qml实现时间轴组件

《基于QtQml实现时间轴组件》时间轴组件是现代用户界面中常见的元素,用于按时间顺序展示事件,本文主要为大家详细介绍了如何使用Qml实现一个简单的时间轴组件,需要的可以参考下... 目录写在前面效果图组件概述实现细节1. 组件结构2. 属性定义3. 数据模型4. 事件项的添加和排序5. 事件项的渲染如何使用

SpringBoot 自定义消息转换器使用详解

《SpringBoot自定义消息转换器使用详解》本文详细介绍了SpringBoot消息转换器的知识,并通过案例操作演示了如何进行自定义消息转换器的定制开发和使用,感兴趣的朋友一起看看吧... 目录一、前言二、SpringBoot 内容协商介绍2.1 什么是内容协商2.2 内容协商机制深入理解2.2.1 内容

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

如何在页面调用utility bar并传递参数至lwc组件

1.在app的utility item中添加lwc组件: 2.调用utility bar api的方式有两种: 方法一,通过lwc调用: import {LightningElement,api ,wire } from 'lwc';import { publish, MessageContext } from 'lightning/messageService';import Ca

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s