当前位置: 首页 > Web前端 > HTML

前端实训:ReactNative开发过程中遇到的坑

时间:2023-03-27 22:50:24 HTML

在开发ReactNative的时候,如果只是写一些简单的页面,基本上按照官方文档reactnative.dev来写就可以了,但是ReactNative有上百个API一、前端培训没有一定的开发经验,面对一些新的需求确实会漏掉重点。这篇文章总结了我个人开发ReactNative遇到的问题和一些冷门API。如果有缘人看了这篇文章,解决了实际问题,那就太好了。1.内置组件本节内容主要是对官网ReactNativeCoreComponents的内容进行补充。主要讲一些不愉快的开发经历,帮助后来人避坑。1、ViewView组件作为最基础的组件,支持半个RN页面。在使用过程中,有几个属性比较冷门,但是个人觉得还是蛮好用的。hitSlop属性:该属性可以扩大View的触摸范围,用在一些小按钮上还是很有收益的。pointerEvents属性:该属性类似于CSS的pointer-events属性,可以控制View对触摸事件的响应。这是一个非常常用的属性。有几点需要开发者注意:Android上存在吞词现象。现象是部分机型最后一个字符不显示,原因不明。当前的折衷方案是在文本的最后一行添加一个空格或零宽度字符。Android有一个名为includeFontPadding的属性。设置为false后,可以减少文本上下的padding(这个padding是为下标字符保留的,比如H2O,2??),可以更好的实现上下垂直居中对齐。在实现文本的居中对齐时,最好在View中嵌套一个Text标签,然后为View设置一些flex属性来控制Text的居中对齐。在web开发中,lineheight属性常用于实现单行文本的垂直居中对齐。这种实现方式本来就是权宜之计,在RN上效果不佳。最佳实践是使用flex属性来实现居中对齐的字体。字体的配置比较麻烦。3、TextInput输入框组件也是一个很常用的属性。个人使用有几个不爽的地方:iOS/Android默认样式比较大。如果没有封装,就会写很多平台相关的代码。当placeholder文本比较长的时候,如果出现换行,是没有API来控制它的行高的。如果一个页面有多个TextInput组件,需要用ScrollView组件包裹起来,实现不同TextInput组件焦点切换的功能4.个人认为ImageImage组件在性能上是很好的,但是有些一些细节入门的同学可能不习惯:CSS中没有那么多滤镜属性,只支持模糊效果。但是,我基本上没有遇到过图像滤镜。加载网络图片时,必须指定图片的宽高。如果不设置size,默认为0。Android上图片尺寸很大的时候(好像是5000px?),不会直接加载图片,但是这种场景很少见,而且tile图片会分步加载,否则图片过大会OOM。iOS/Android对webp的支持不是开箱即用的,需要单独配置:iOS使用SDImageWebPCoder提供支持,Android使用fresco提供支持,Android不支持点9图5.ModalRN有一个明显的问题之前官方提供的Modal组件,Modal无法覆盖状态栏。比如我们做了一个弹窗,背景是黑色半透明的,但是状态栏是白色的,感觉上很零散。幸运的是,0.62版本有一个statusBarTranslucent属性,可以设置为true来覆盖状态栏。如果是0.62以下的版本,需要改一些配置。6.ScrollViewScrollView组件是RN提供的一个滑动容器组件。我将在这里解释一些不受欢迎但有用的API。第一个是天花板功能,涉及StickyHeaderComponent和stickyHeaderIndices两个API,可以实现滚动天花板的效果,非常好用。第二个是automaticallyAdjustContentInsets属性。iOS滚动列表有时会出现莫名其妙的空白区域。这是由iOSNative层实现的。RN的具体触发时机我没有做过详细测试,但是基本上关闭这个属性就可以绕过。7.FlatListFlatList主要注意三点:FlatList提供了自定义的header/bottom/blank/separationline组件,比一般的web组件封装更彻底。有些React在渲染列表的时候会要求添加key来提高diff性能,但是FlatList封装的很多,需要使用keyExtractorAPI来指定listCell的keyFlatList性能优化内容。官网写得不是很好。第二,内置API。这一段的内容主要是补充一下官网ReactNativeAPI的内容,主要是说一些让人开发不舒服的地方,帮助后面的人避免掉坑。1、AppStateAppStateAPI在实际开发中主要用于监控APP的前后台切换。这个API在iOS上是语义一致的,但是在Android上就存在问题,因为Android上AppState的实现实际上是基于Activity的生命周期的。比如AppState提供的后台状态,其实是基于Activity的onPause(),但是根据Android文档,执行onPause()有几种场景:APP切换到系统后台(如预期)当前RN容器Activity上层覆盖新的Activity(与预期不符)当前RN容器Activity上层覆盖Dialog,比如权限申请弹窗(Dialog本质上是一个半透明的Dialog)(与预期不符)综上所述,使用AppState来监控APP的状态,需要充分考虑Android的这些“异常”表现是否会导致程序bug。2、PermissionsAPP平台的权限管理是一件很繁琐的事情。RN官方只提供了PermissionsAndroid,并没有提供跨平台的权限管理API,使用起来非常不方便。这里我建议使用react-native-permissions库,这样更容易管理权限。3、EventRN官网没有暴露Event相关的API,但是RN导出了DeviceEventEmitter这个“发布-订阅”的事件管理API,使用起来也非常简单,如下例所示。import{DeviceEventEmitter}from'react-native';//triggerDeviceEventEmitter.emit('EVENT');//monitorconstlistener=DeviceEventEmitter.addListener('EVENT',()=>{});//移除监听器.remove()4.AnimatedRN动画API,说实话,掌握成本比较高。光是官方API就涉及到Animated、LayoutAnimation、Easing、useNativeDriver等概念,文档分布比较分散。初学者很难构建完整的脑图。想要构建性能更高的动画,就得学习react-native-gesture-handler、react-native-reanimated等第三方库的API,学习成本飙升。这里推荐ReactNativeAnimationBook,一本在线书籍,基本上是手把手的教学。看完之后,你会对RN的动画API有一个整体的了解。3、第三方LibraryReactNative逐渐将一些非核心组件交给社区维护,比如webview、async-storage等,还有一些非官方但有用的组件,比如react-native-svg、react-native-camera等除了这些Native相关的第三方库,JS社区中的宿主无关的JS库也有,比如lodash、redux等纯逻辑库。由于第三方库太多,这里就不一一列举了。4、特效ReactNative的style属性只提供基本的布局属性,比如flexbox布局,fontSize等。但是对于很多CSS3特效属性,ReactNative基本上都得引入第三方库。整理了几个常用的UI效果使用的属性和插件,方便开发者使用。1、圆角效果可以直接使用Viewstyles属性的borderRadius。RN还支持设置View四个角的单独弧度。2.模糊效果模糊效果使用RN官方社区库@react-native-community/blur。这个RN模糊库比CSS的blur()属性更强大。CSS只支持高斯模糊。这个库至少支持三种模糊效果,具体效果还需要跟UED商量。3.阴影效果Shadow可以使用RN提供的ShadowProps,但是它是平台特定的:iOS提供了四个属性shadowColor、shadowOffset、shadowOpacity和shadowRadius,与CSS的box-shadow属性完全对齐,可以满足大多数Android只提供了shadowColor和elevation这两个属性,而严格来说,elevation其实就是“仰角”的意思,这是Android官方提供的一个属性,模拟现实中自上而下光照引起的阴影变化。虽然有一套理论,但是在实际开发中,你会发现elevation产生的阴影非常难看,这和iOS完全不一样。就个人而言,我通常建议使用渐变而不是阴影。4.渐变效果Gradient需要用到第三方库:react-native-linear-gradient,就像库名一样,本仓库只提供“线性渐变”方案。从个人经验来看,线性渐变在大多数情况下已经足够了。如果你想使用“径向渐变”,你可以使用react-native-svg的RadialGradient组件。五、可视化Web平台除了最基本的

标签外,还支持SVG、canvas等自由度较高的绘图API。它们支持大多数可视化场景,例如各种自定义图像和图表。下面简单介绍一下RN中对标Web的一些第三方库。1、SVGRN对SVG的支持是基于react-native-svg仓库。就个人体验而言,与Web的SVG功能基本一致。除了自己绘制一些自定义的SVG外,作为底层库,它还有更多的功能来支持上层图表的使用。2、canvasRN类中没有canvas的概念,市面上也没有canvas好的替代品。一些开发者创建了react-native-skia,也有一些demo。但目前还是实验项目,生产环境风险还是太大了。不过就我个人的经验来说,很多绘图功能都可以基于SVG来实现,必须用canvas的应该很少见。基于skia,可以集成flutter进去,可以玩套娃游戏:)3.移动平台支持OpenGL。WebGL是浏览器平台对OpenGLES的封装。RN本身已经非常接近Native平台,所以没必要再支持WebGL,直接支持OpenGLES即可。目前RN对OpenGL的支持是基于gl-react,底层适配层是基于expo-gl。因为没有做过RN3D相关的需求,所以无法对库做出准确的评价。需要读者自行判断。4.图表功能图表是一个很现实的需求,在一些B端场景中经常会有报表需求。因为RN只是对SVG的支持比较好,所以RN的图表基本都是基于SVG绘制的。网上有很多基于SVG的图表库,但RN能用的可能不多。主要原因是RN和Web的宿主环境不同。一些图表库可能会使用Web特定的API(例如getElmentById),而像ECharts这样的库是RN肯定无法使用的。可以迁移的库一般满足两个条件:纯逻辑:D3.js一些纯逻辑库,只使用JS的语言能力平台无关:直接基于React,不使用平台特定的API5。海报功能海报分享是现在很常见的前端功能。网页基本都是基于canvas生成分享海报。虽然RN没有很好的canvasAPI,但是有一个很好的库——react-native-view-shot,可以写RNView生成图片。借用这个库可以在APP本地生成图片,进而实现海报功能。原作者:卤代烃