本文介绍ReactNative入门相关知识, 包含一下知识点
没有完美的跨端技术,只有适合的场景
RNApp 上Weex 最终未能大规模流行起来,Flutter 使用的语言是 Dart 而非 JavaScript,并不能很好支持动态更新React Native 是一个非常流行的跨端框架,开发者认可度很高 npm trends上面RN增长势头强劲React Native 是一个跨领域的融合技术,它是你现有技术的自然延伸。React Native 新架构 与2022年已经发布Hermes 是一款专为移动端打造的 JavaScript 引擎,它支持 JavaScript 的 AOT 预编译。node.js 使用 addon 调用 C++ 、 Flutter 用 FFI 调用 C++ ,以及 Java 使用 JNI 调用 C++ 一样。Airbnb 的自行研发服务端渲染框架原理非常类似React Native 老架构之上实现了 SSR,据说美团的页面渲染速度最快能达到 50ms。首先贴出 官方文档
官方写的很文章很详细完整,我不再累赘。建议严格按照官方文档一步一步操作(比如jdk安装了其它版本,作为外行人很难定位问题,这样学习效率不高)。推荐 完整原生环境
我使用的是苹果电脑,本文也是讲解MacOS 系统下RN环境安装问题(一般RN开发都是用mac电脑,虽然window电脑可以通过安装虚拟机xcode 来解决ios构建问题,但该方案比较偏,问题也多)
但由于众所周知的原因,国内用户会遇到各种奇奇怪怪得问题。我这里记录一下我在安装过程中遇到的问题及解决方案,供参考。
作为前端node安装不用说了(其它nvm、yarn/npm、 nrm/yrm等可以参考我的其它文章,这里不说这些)
补充一些墙问题的解决方案
ClashX 客户端,参考网上的教程mac顶部状态栏 ClashX 图标 打开本地配置文件,第一行就是 mixed-port: 7890推测这个就是端口export ALL_PROXY=socks5://127.0.0.1:7890curl -vv https://www.google.com 命令,验证是否解决命令行墙问题为什么我的终端可以翻墙 却有些包还是下载不了?
ping github.com 控制台日志 Request timeout for icmp_seq 表示丢包,网络不通,github.com 得到 ip 为140.82.113.4 配置host 140.82.113.4 github.com ,再次使用ping github.com测试,网络已通。(pod install安装失败,可以用此方案解决)安装失败问题
pod install安装失败,再次执行会从上次下载失败的包处开始重新下载)brew 问题
brew install watchman 或 brew update 等阶段,可能会遇到的报错信息 Error: homebrew-core is a shallow clone。homebrewXcode 安装问题
app store里xcode一直转圈,过一会提示 “无法下载请稍后再试”xcode 链接这里 过了一会下载完成解压后拖拽到应用 覆盖原有的xcode ,至此xcode安装成功watchman 问题
yarn ios 或yarn android时报错,即使在安装时正常 ,也可能第二天你执行yarn ios或 yarn android时报错,报错内容为
ios或anroid机器(这里的机器包含真机或模拟器)上 还会看到全屏报错
Document目录移出,可以移动到 ~/** 目录 (~/是用户主目录)cocoapods 问题
brew install cocoapods失败,可以用sudo gem install cocoapods试试看,iOS项目问题排查
yarn ios./ios目录 双击.xcworkspace文件,在xcode中打开项目
补充一些知识点:
Watchman 由 Facebook 提供的监视文件系统变更的工具Xcode 苹果生态应用开发唯一工具,这里开发ios app 就有用的xcode构建CocoaPods IOS包管理器,命令行pod, 可类比web前端的npmHomeBrew macOS的套件管理工具,命令行brew,可以类比unbuntu的apt-get或centos的yumMetro 它是RN的打包工具,类比web前端的webpack首先补充下android相关知识背景
jdk与jre的关系
jdk是java开发工具,编译java文件为二进制文件(.classes);jre是java运行时环境- 查看
jdk版本java -version; 查看jre版本javac -version; 查看jdk路径which javaorwhereis java- 卸载
java sudo rm -rf /Library/Java/JavaVirtualMachines/jdkxxx.jdkgradle这里可以理解为 android项目构建工具, 可以把它看作保姆,下载资源并配置,可以写动态脚本。包含maven的功能,maven/pox.xml可类比web前端的npm/package.jsonAndroid Studioandroid开发官方推荐的JIDE
Android Studio内置了很多东西(jdk、模拟器、adb等)- 其中有接触过android webview 调试的同学可能了解
adb,如果你想使用adb命令可以使用IDE内置adb
yarn android 如果严格按照官方文档来,android环境的安装会比较顺利
jdk再配置IDE,如果你先安装配置了IDE,系统会自动为你安装jdk,此时你使用yarn android是跑不起来的。jdk 按官方文档安装jdk,然后删除项目重新安装npx react-native init AwesomeProject,最后在执行yarn andriod才能正常跑起项目模拟器运行
error Failed to launch emulator. 或者 > Task :app:installDebug FAILEDadb device 检测设备, 如果没有 则打开Android Studio 删除设备, 在重新创建adb devices检查电脑是否识别手机,只要能识别到手机就能真机运行!假设经过上面的前面的折腾,你也像我一样成功把脚手架跑起来了。

万事开头难,环境搭建多折腾
最早期的版本叫做热重载 HotReload 基于Webpack的模块热替换原理开发的

2) Metro收到通知就会编译涉及到的更新文件
3) 编译完成会生成一个用于更新的bundle文件
4) 本地服务会通过socket通知客户端
5) 客户端请求资源
6)服务端响应bundle,客户端在原来的RN应用的JS执行上下文中运行更新的bundle
基础的模块热替换只能实现组件级别的强制刷新,而组件的状态会丢失,如何复用组件的状态呢?
RN在运行时,用“代理”的方式管理新旧组件的切换
原生视图会复用吗?
肯定复用,RN组件进行render时判断是否需要创建原生视图,通过浅层比较决定是否复用原生视图。

当然,并不是所有情况都会复用状态和原生视图。
对于函数组件来说,hooks 的顺序非常重要, 如果hooks顺序有变化,会丢弃原先状态,新建原生组件
对于类组件 只要是类组件的代码发生更新,组件的内部状态都要重新初始化。
建议:尽可能地拥抱函数组件,放弃类组件。
默认的脚手架启动后,页面展示的是调试文档和学习指引文档。
调试文档如下:(以下操作前提是选中模拟器)
Command + M(android模拟器)/Command + D(ios模拟器) 或摇晃手机(真机) 弹出开发者菜单选项 (android机还可以通过adb shell input keyevent 82)
几种调试方法的对比

Terminal调试
chrome调试Flipper Facebook 出 。它的功能很强大,打日志、打断点、查看元素树、抓包请求、查看存储它都支持,而且支持扩展插件。凑合参考这篇《用Flipper调试React Native应用程序》文章吧
与环境搭建一样,坑很多。。。
这里记录一下步骤和踩坑点
brew install --cask flipper 注意命令行要翻墙,否则安装不了flipper 会有警告 “不明开发者,,移到废纸篓”, 千万别移到废纸篓, 在 mac偏好设置--》安全与隐私--》点击仍然打开flipper, 这时要检查环境配置
放心没那么顺利,上图是我处理后的
SDK Installed 要选择路径,可以查AndroidStatio的设置,我的配置为
flipper的 React DevTools和Logs调试 (亲测android模拟器和ios模拟器有效)


adb devicesadb install -r xx.apkadb reverse tcp:8081 tcp:8081adb shell 进入沙盒类linux命令行环境adb push 1.png /sdcard/ copy电脑文件到手机adb pull /sdcard/1.png ./ 从手机中copy文件到电脑txtandroid |-app |- src |- main |- AndroidManifest.xml |- java |- mainApplication.java |- res |- minmao-hdpi / minmao-mdpi 应用图标 |- minmao-xhdpi / minmao-xxhdpi / minmao-xxxhdpi |- values |- string.xml 修改应用名称 |- build.gradle |- build.gradle
AndroidManifest.xml
外层build.gradle大概率改不到
内层build.gradle
mainApplication.java

Java / KotlinOC vs Swift.jksbuild.gradle文件中的releasePUSHY RN中文网推荐Code Push 由于墙的原理网速比较慢,第二体检热修复包的设计思路
RN的本质只克隆了一份React并对react-dom进行了重写

用一张图对比下webview壳与RN两种混合开发上的差异

老架构的核心问题是JSBridge的性能瓶颈
UI Manager React创建FiberTree后会通过bridge再渲染原视图组件,这块开销也大新架构使用JSI 替换了Bridge,我们先来看一下架构图

JSI
JSI 是一个轻量级的通用层,用C++编写,JS引擎可以使用它直接执行或者调用native。
JSI 如何让 JavaScript 直接调用到原生方法?
在 JSI 里 Native 方法会通过 C++ Host Objects 暴露给 JS, 而 JS 可以持有对这些对象的引用,并且使用这些引用直接调用对应的方法
Fabric
Fabric 是新的渲染系统,它将取代当前的 UI Manager。
使用新的 Fabric 渲染,用户交互(如滚动、手势等)可以优先在主线程或 Native 线程中同步执行,而 API 请求等其他任务使用异步执行。
另外新的 Shadow Tree 将成为 immutable,它会在 JS 和 UI 线程之间共享,以两端进行直接交互。
Turbo Modules
Turbo Modules 基本上是对这些旧的 Native 模块的增强。
仅在需要时才加载对应模块,这样可以将显着缩短 RN 应用的启动时间。
Codegen
Codegen 主要是用于保证 JS 代码和 C++ 的 JSI 可以正常通信的静态类型检查器,通过使用类型化的 JS 作为参考来源,CodeGen 将定义可以被 Turbo 模块和 Fabric 使用的接口,另外 Codegen 会在构建时生成 Native 代码,减少运行时的开支。

总结
本段参考资料
本文作者:郭敬文
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!