React Native

  • JavaScript性能差于Dart, React Native的桥接层又大大损失一部分性能, 导致React Native的性能远差于Flutter.
  • 启动缓慢.
  • 由于RN项目会同时包含Android和iOS的工程文件, 导致项目升级困难.
  • 社区维护的项目模板过旧.
  • 项目不是原生TypeScript的, 编译过程依赖于大量不可手动维护的babel转换插件.
  • 官方提供的原生功能比较少, 大多数原生功能都需要通过社区模块实现.
  • 缺乏自定义组件的功能, 自定义组件需要手动编写对应平台的Native模块.
    这项缺陷导致React Native在Flutter这类统一渲染层的解决方案面前失去竞争力.
    潜在解决方案:
    • 阿里巴巴开发的GCanvas(一个跨平台Canvas方案)是少数正面解决此问题的方案, 然而它没有使用价值:
      这是典型的阿里系KPI项目, 该库的Weex和React Native支持都已停止维护, 软件的核心包也完全无人使用.
      由社区维护的react桥@flyskywhy/react-native-gcanvas也严重缺乏下载量, 不太可能发展为流行选择.
    • 基于WebView的Canvas的react-native-canvas.
    • react-native-svg, 该库提供了自定义形状的功能, 然而性能很差, 以至于无法使用.
  • 社区缺乏一个富文本编辑器组件, 现有的组件都是基于WebView的,
    而基于WebView的富文本编辑器不仅性能差, 还无法实现一些功能.
    现阶段如果需要使用富文本编辑器, 则推荐基于Quillreact-native-cn-quill.

由Facebook开发, React Native专用的bundler.

  • 不支持解析子依赖项的exports字段:
    https://github.com/facebook/metro/issues/670
  • 不支持 .cjs.mjs 扩展名:
    https://github.com/facebook/metro/issues/535

一个用于快速开发App的服务, 开发人员可以避免接触平台的Native代码.

使用Expo时, 无需在开发机上安装Android Studio和Xcode, 只需要有相应的移动设备即可进行开发和调试.

Expo与当前的RN主流开发方式关联紧密, 官方文档和组件库里里会经常出现Expo的字样.

在SDK v43以前, Expo使用自己的React Native fork, 官方在此之上支持被称为Expo SDK的一系列Native软件包.
从SDK v43开始, Expo直接使用官方的React Native模块.
开发人员是面向Expo SDK进行开发的.

Expo SDK有自己的版本号, 每3个月发布一次, 向后兼容性保持6个月.

Expo SDK也支持被添加到现有的React Native项目中.
在SDK v43以前, 这需要安装一个名为react-native-unimodules的包, 安装此包需要编辑大量Native代码.
从SDK v43开始, 可以使用 npx install-expo-modules 安装任何Expo模块.

Expo有自己的OTA功能, 可以在不更新App的前提下完成App的动态升级.

Expo的OTA可以自托管:
https://docs.expo.dev/distribution/hosting-your-app/

Expo支持的一种自行构建App的方式.
https://docs.expo.dev/distribution/turtle-cli/

  • iOS和Android API的封装覆盖面有限: Expo SDK只提供了一部分常用的API.
  • 生成的应用程序包很大, 普遍超过50MB.
  • 除非弹出(eject), 否则无法使用自定义Native代码.
  • 供应商锁定很严重, 弹出(eject)带来的问题很多, 不亚于重写整个程序.
  • 不支持Headless JS
  • 不支持Expo, FCM, APN以外的推送通知服务.
  • 支持平台的最低版本号受限制, 目前是Android 5+, iOS 10+.
  • Expo应用的构建是通过服务远程排队运行的, 有时会需要排很长时间的队.
  • Expo SDK的依赖项版本经常落后
  • 不支持需要后台运行的App.
  • 不支持E2E测试
  • 不支持应用内购买(IAP)

Expo不支持的热门需求: https://expo.canny.io/

在iOS和Android里都能使用的后台任务管理模块.

该模块的后台任务是由系统调度的, 因此会有最短调用间隔和执行时间的限制, 只适合周期性任务, 有很大的局限性.

  • 模块模板, TypeScript+Kotlin+Swift: https://github.com/demchenkoalex/react-native-module-template
  • 项目模板, TypeScript+Kotlin+Swift: https://github.com/demchenkoalex/react-native-better-template

React Native for Web.

一个将React Native组件带到Web上的库, 从而可以在Web上直接使用React Native的代码.

遗憾的是, React Native for Web的兼容性较差, 因此部分组件不会像iOS和Android上那样工作.
因为这个原因, 无法指望通过React Native for Web创建可用于生产的Web应用.

React Native for Windows(UWP).

该项目实际上还提供React Native for macOS.

基于任务注册的后台数据获取, 有很大的局限性.

可定制图标库.

https://github.com/zo0r/react-native-push-notification

https://github.com/wix/react-native-notifications

https://github.com/invertase/notifee

移动设备优先的React Native组件库.

这个项目搞了一套自己的样式语法, 很容易陷入供应商锁定.

https://github.com/akveo/react-native-ui-kitten

基础组件库.

https://github.com/react-native-elements/react-native-elements

https://github.com/itinance/react-native-fs

读写文件系统, Android访问文件系统时需要向用户申请权限.

开箱即用的调试器.

https://www.npmjs.com/package/react-native-game-engine

一个简单的游戏引擎, 维护并不积极, 用户数量也很少.

react-native-game-engine使用requestAnimationFrame作为游戏循环.

Image的替代品, 提供高性能图片显示.

与expo兼容的方案, 是一个纯JavaScript实现, 被官方团队推荐使用.

社区最多人使用的导航方案, npm下载量远大于react-native-navigation.

该库也实验性的支持在react-native-web上使用:
https://reactnavigation.org/docs/web-support/

react-navigation在引擎盖下使用此模块.

与expo不兼容的方案, 需要本机模块, 性能比react-navigation更好.

Android对阴影的支持与其他平台不同(只支持用elevation属性调整元素的"高度", 让程序自动计算投影面积),
用这个库可以实现跨平台一致的阴影效果.

缺点: 性能很差.

仍在维护的Swiper/Carousel组件.

https://github.com/wix/react-native-calendars

日历组件.

Hermes是React Native在Android上使用的转为移动应用优化的AOT JavaScript引擎,
从React Native 0.64版本开始, 该引擎支持iOS.
Hermes相比平台上自带的JavaScript引擎(浏览器使用的引擎), 在各种指标上都表现优异, 提升近1倍.

Hermes不是默认启用的, 需要用户手动开启此特性.

使用Service让React Native应用的JavaScript代码能作为服务在后台运行, 仅Anroid可用.
需要通过Java创建启动服务的Intent:

Intent serviceIntent = new Intent(context, MyTaskService.class);
context.startService(serviceIntent);

在早年的Android系统里, 应用程序的Service有别于Android的Activity, 不会优先被内存管理器杀掉.
但如今很多系统的内存管理器变得比过去更严格, Service不会比Activity活得更久.

教程: https://medium.com/reactbrasil/how-to-create-an-unstoppable-service-in-react-native-using-headless-js-93656b6fd5d1

描述组件的类别.

描述组件是什么.

描述与组件交互会发生什么.

用于描述组件值的一个对象.

常见用途是描述Range之类的有取值范围的组件.

用于描述组件当前状态的一个对象.

常见用途是描述Checkbox, Details之类的有状态组件.