react-native实践

使用rn开发已经有3个项目,历经15个月的时间了,比较遗憾的是原生方面还是没有深入研究过,其他部分先记录下来吧。后续有机会更深入了解再补充文章。

关于react-native的优劣

  • 优点
  • 跨平台

  • 开发体验良好,比如像hot reloading

  • 基于react,前端开发者上手快,开源生态丰富

  • 缺点
  • js报错会导致应用直接闪退,目前也没发现错误捕捉这方面一套完整的第三方解决方案

  • 有些第三方库跟本地rn版本不一致,或者是第三方库sdk版本不一致都会报错,有的是编译时报错,有的是运行时报错

  • rn版本更新很快,有时候升级很麻烦(比如我在47升级到55过程中产生了很多问题,从55.0一直到57.7才稳定下来)

  • 同时使用pod的话需要手动注释引入的库,而且初始化该项目的时候会报一个rnpm-install ERR! Something went wrong while linking. Error: Cannot read property 'match' of undefined的错

  • debug比较麻烦

  • 集成sdk需要一定的原生知识

导读《React Native at Airbnb》—— 为什么 Airbnb 放弃了 React Native?

[不负责任的]react-native适用场景总结

TODO:这部分需要一些图示/demo支持**

  • rn适合用于原生应用中替代h5的部分。rn有接近web的开发体验,相对于h5的响应速度更快,另外在taro等类似的框架下还能同时开发h5/rn,以上结论仅凭实践经验,还需要更多的测试数据支持。

  • rn适用于迭代快、功能简单的应用开发。例如有些应用在初期阶段的UI调整比较频繁,除了高效的开发体验外,可以通过覆盖安装/热更新等方式实现应用的快速迭代,往后业务逐渐稳定后再考虑更深入的优化性能。

记录一下实践中的经验

已实现的功能列表

rn提供的功能例如Linking等就不在列表里赘述了

  • 基于jpush的推送功能

  • 基于code-push的热更新功能(可以自建服务器)

  • 基于bugly的apk更新、crashReport功能

  • 基于react-native-splash-screen的开机启动图

  • 基于react-native-image-picker的本地相册/相机获取

  • 集成微信sdk的分享/支付功能

TODO LIST

  1. 应用中的埋点上报处理的比较简单,仅在关键节点收集数据后进行实时上报,实际上可以处理的更好,日后再研究一下怎么完善这个解决方案。

可以参考一下苏宁流量数据采集体系的演变

  1. shadow在android端不能实现,使用react-native-shadow或是其他svg等方案与ios端的效果差距较大,目前是减少投影效果,在部分设计强需求的情况下使用图片替代。

  2. react-navigation中,第二个参数为object,如何在产生路由变化时(例如navigate/replace等方法)对该参数进行校验,否则当该参数被调用时不存在会抛出错误,进一步的,如何在例如lint等方法执行时对这些方法的第二个参数进行校验(那么如何配置这些校验方法呢?)。

  3. bundle应该怎么分析,怎么进行优化呢?

  4. 项目的质量体系如何组成,目前仅是lint+jest,保证代码风格的统一,维护全局组件/方法的正确调用,但是对组件/页面级别的质量分析是缺失的,这部分该如何进行?除此之外,还有哪些质量体系的组成部分?

  5. 目前是hot-reloading+debugger,还有更好的调试方法么?

bug list

  1. android端会因为图片尺寸过大,造成内存溢出导致应用闪退,如何在客户端去兼容这些大尺寸的图片呢?

  2. 当前的错误捕捉机制可以在大部分设备上有效的拦截错误,阻止应用闪退,但是有些设备如htc等,render的错误依然会导致应用闪退,如何针对这些设备去分析该错误的传递机制,如何进一步的完善该错误捕捉机制呢?

开发环境下的调试

react-native-debugger 是一个非常好用的调试器,集成了remote debugger & react inspector & redux devTools,可以使用它来替代官方文档中的调试工具。(运行时间过长会导致cpu占用过高)

请求封装与参数校验

由于旧版项目中的请求,都是直接在业务代码中进行fetch的配置,导致业务代码产生了‘意大利面’的情况,包括多次配置重复的header、重复定义每次的错误捕捉、大量的魔法字符串等,另外也会产生比如一个接口对应多个地方需要使用,但由于没有实现统一的调用不能及时的在每个地方同时修改,所以对应服务端controller的管理,在本地也建立了一层service的设计,用于请求的声明、配置、参数校验。

封装的目的:

  • 统一的url拼接

  • 统一的header配置

  • 统一的请求自动化校验,比如超时处理、网络检测等

  • 统一的格式化处理

  • 统一的错误处理(见下文异常分析),同时抛出提示给用户,根据需求是否对继续下一步流程

以上的处理,显著的减少了由于参数产生的请求异常,通过promise的链式调用大大的简化了业务代码的复杂度。

异常捕捉

  • render的错误捕捉

通过在顶级组件内配置componentDidCatch可以上报错误的堆栈,由于release版本下的rn会将js打包为一个bundle,需要引入source-map,生成/从服务器获取bundle(热更新的话,是推送新的bundle到服务器),配置堆栈,可解析得到具体报错文件的行列信息。

  • 应用崩溃的错误捕捉

bugly提供了crash report的功能,提供了应用崩溃时的error信息及常见的解决方法,还可以配置userId结合该用户的路由变化分析该错误的形成。

  • global

global.ErrorUtils.setGlobalHandler((error, isFatal)=>{

// your handler here

});

可以通过该方法配置自定义的异常处理,源码位置

  • 请求的错误捕捉

通过与服务端的约定得知,http code !== 200即为非正常返回,response内标志符失败为非成功返回,这2种情况下返回reject,其余为正常情况返回resolve(通过和其他的工程师交流,有认为这类错误应该指是promise方面产生的错误进行统一的捕捉,此处仅为针对response的处理)

返回reject是因为有些业务场景下,需要在请求返回为失败的状态进行下一步处理

错误分析

由于react-native是将js打包成为bundle启动时加载,在release版本下收集到的堆栈信息难以定位,可通过source-map在分析对应的bundle得到精确到出错文件的堆栈。(跟其他工程师交流了一下,这个功能可以放到服务器上做一个可视化开发,满不错的想法)

更新机制

分为apk更新及热更新,原生代码改动后需要覆盖安装,js代码可通过热更新重新下载bundle。

apk更新

采用了bugly的方案,内置集成该功能,可通过后台上传新的apk包,配置更新策略,应用运行时会自动检查更新。(ios端只能通过app store上传,我在项目中是开机后通过请求检查是否有新版本,是的话跳转到app store)

这里有个问题,通常上架到不同的应用市场配置不同的APP_CHANNEL,那么这里覆盖之后怎么解决统计来源?**

热更新(注意上架的应用市场对这方面的限制)

采用了react-native-code-push的方案,可以将服务自行配置到国内的服务器上,通过命令可以将当前代码打包上传至服务器。(这里服务器中的bundle可以跟上文提到的source-map配置到CI系统里)

其他

  • 如果存在与h5的交互,可以抽象一个内置WebView的组件统一进行调用,实现注入、唤起外部app(分享、支付等场景),onMessage有安全风险,需要通信怎么处理比较合适?

  • 有些动画效果在android端使用Interactionmanager可以更流畅/正常执行

  • 富文本的解析是通过WebView的自动计算高度实现,在android/ios触发的方式不同

xcode一些编译时报错的解决方法

  • LPod link error的错,移除之后clean再打包可解决

  • rnpm-install ERR! Something went wrong while linking. Error: Cannot read property 'match' of undefined的错,Podfile在end之前添加一句# Add new pods below this line即可解决

比较好用的第三方库

react-native-community里面有很多很棒的项目就不重复了

  • react-navigation 路由

  • react-native-code-push 热更新

  • react-native-image-zoom-viewer 图片放大

  • react-native-gesture-handler airbnb出的手势控件

  • react-native-snap-carousel 支持多种样式的轮播图

  • react-native-splash-screen 启动屏配置

  • react-native-iphone-x-helper 支持iphoneX等大屏设备检测

  • react-native-root-toast 支持toast提示

  • parameter 死马的一个参数校验库

你可能感兴趣的:(react-native实践)