-
Notifications
You must be signed in to change notification settings - Fork 4
React Native采坑日记
-
环境错误
第一次接触
RN
,肯定是从配置环境入手,完成了双端的编译运行,这仅仅是个开始 关于RN的各种报错原因及解决方案,可以参考这位大神的总结
React Native开发错误警告处理总结(已解决 !持续更新补充:
如果偶尔遇到了一些网上搜不到的报错信息,或者尝试了网上的方法无效,不妨关掉Debug模式,关闭调试浏览器页面,关闭模拟器,关闭js服务,重新run一次,偶尔的情况下,不做任何调整就能恢复正常,还有调试模式下无法断点拦截,或者断点错位,都可以试试
我在配置RN环境中遇到的错误及解决方案总结 -
flex
布局第一次使用
flex
布局,上手写了个非常非常简单的界面(修改密码功能),写完后跑在Android
机上,键盘弹起后,发现控件的高度被挤压了.....- 解决方案:
- 设定高度
-
display
: 布局中使用了绝对布局,那么display
将在Android下失效解决方案:
设定控件的宽高,来达到控件显隐的控制效果
-
TextInput
: iOS下TextInput
中文BUG
解决方案:
RN版本还处于不断更新完善中,项目中一旦决定采用了某个指定版本,一般不会轻易升级RN版本,例如我们项目使用的是
v55.4
,iOS
下TextInput
输入中文的BUG
相信不少人应该遇到过了,网上也有很多临时解决方法,但我感觉都不太完善,按照网上的方法可以解决原生输入法的问题,但是在搜狗输入法下还是会有点问题,在后续的RN版本中已经修复了这个BUG,由于项目不打算升级RN版本,采取了修改源码的方式来修复这个BUG,麻烦的就是,要修改开发环境的源码,同时还要修改构建机源码,避免今后构建机npm install
后问题复现,还要在脚本中特殊处理,避免今后出现问题TextInput Fix controlled TextInput for Chinese (and other languages) #18456
-
stickyHeaderIndices
会导致后一个控件二次调用componentDidMount
方法用过RN的人不一定熟悉这个属性,它是ScrollView用于控制内部某个子控件是否悬挂的,如果你的页面没有什么特殊场景,可能不会造成什么影响,然后我们需要悬挂的是个
WebView
,内嵌了一个H5的MapView
,别问我为啥这样,因为这样就不需要客户端挂VPN了,同时这个控件下面的界面稍微复杂一点,是单独封装了一个用于展示路线的控件,包括途径地点,两点之间的出行方式,详细步骤等介绍解决方案:
调整控件顺序,尽量找一个即便是
componentDidMount
被多次调用了,也不会产生什么影响的控件在悬挂控件下面,如Modal
的控件 -
FlatList
的ListFooterComponent
列表中常见的场景,当列表数据全部加载完毕,会提示“全部加载完毕”, 先描述下我的实现方式 界面顶部一个导航栏,下面一个列表触底,界面布局没有使用
Flex
, 而是通过屏幕的高度直接限定 当显示"全部加载完毕"时,iOS
下正常,而Android
下没有显示,正当我一脸懵逼的时候,给ListFooterComponent
加了个背景色,给FlatList
加了个marginbottom
,发现Android
的ListFooterComponent
这货超出屏幕了解决方案:
起初的解决方案是,在Android下加了一个间距,最后是设置了
render
中最外层View
的flex
-
react-native-view-shot截图,
Android
下报错:Trying to resolve view with tag XXXX which doesn't exist
on Android, getting "Trying to resolve view with tag '{tagID}' which doesn't exist"
- you need to make sure collapsable is set to false if you want to snapshot a View. Some content might even need to be wrapped into such to actually make them snapshotable! Otherwise that view won't reflect any UI View. (found by @gaguirre)
Alternatively, you can use the ViewShot component that will have collapsable={false} set to solve this problem.
- 先来说下界面结构:
-ScrollView
----WebView 需要截取的控件
----View 绝对布局的一个遮罩层
-ScrollView业务需求,整个页面都是H5写的,当点击截屏的时候,
H5
会将WebView
中的H5
页面完全展开,返回一个高度,然后RN这边根据高度截取整个H5页面,本身我是一个iOS Developer
,按理讲WebView里面也是有个ScrollView
的,但是截屏后死活不对,只有一屏大小;于是将外层View
节点改成了ScrollView
,当截屏的时候,重新设置WebView
的高度,将ScrollView
撑起来,iOS
可以了,但是Android
上一跑,就红屏了,报这个错误,按照方法试过无效,也有说设置背景色的,仍然不行,最后调整了下布局,直接截ScrollView
;这还没完,iOS
模拟器上截图模糊,而Android
一直是真机运行没有此问题,后来改用iPhone
真机调试,没有了模糊的问题,但当H5
页面展开过长,截取的图片为纯白色空白页面,起初怀疑和ScrollView
嵌套Webview
有关,但通过demo
排除,暂时留存,打算后面再通过分段截图的方式处理 -
ReacNative
:iOS
正常,Android
报错Cannot add a child that doesn't have a YogaNode to a parent without a measure function!
写好一个界面,iOS跑完全没问题,Android直接Crash,提示
ReacNative:报错Cannot add a child that doesn't have a YogaNode to a parent without a measure ...
这类信息,一脸懵逼,网上搜到了这篇文章:传送门,因为界面内的所有模块都是抽出去写的,然后开始定位排查,最终定位到一个页面,在View
标签中间多了空格,我使用的环境是VS Code
,虽然VS Code
有自动保存的功能,但我使用任何工具都习惯默认状态,每次写完代码Alt + Shift + F
,然后CMD + S
, 但是对于View标签间没有子控件的情况,并不会帮我去空格,因此发生了这个BUG建议:这类没有内部子控件的标签,尽量使用自闭和标签, 如
<View/>
-
用户授权
当App中需要用到相机,访问一些传感器就会需要获取用户授权,在最初接到这个需求的时候,翻了翻RN的资料,然后发现了一个别人封装好的组件
react-native-permissions
,以前对Android
适配稍微有点了解,刚好手上就有一台华为测试机,经测试效果还可以,正当我美滋滋的完成任务构建送测,测试那边反馈,两台小米都没有任何反应,开始排查问题...发现在小米手机上直接失败,考虑到国内手机厂商对Android
的各种所谓‘定制’,RN
默认提供的方式可能有些‘不接地气’,另外遇到的一个恶心的地方是react-native-permissions
导致上TestFlight
处理完一闪消失解决方案
Android
稳妥起见,我先检查授权情况,如果授权失败了,自己再加个Alert
,提示跳到系统设置页手动开启权限
iOS
也是授权问题,当时没看这个库的源码,里面使用了很多我们未曾用到的权限代码,,在plist
中全部加上即可缺点是
个别机型通过获取授权能够弹出提供授权选项,会遇到多次弹框,而之前发现有问题的小米机型上指挥收到一次自定义弹框。
为啥没有跳到对应App的权限设置页,因为我对Android
不熟,搜出来了适配所有国内手机厂商的代码,看的我难受 -
2020-07-20
好久没写过RN
了, 换了设备随着上次升级TypeScript
这次重新回到RN
又一次升级了, 重新搭建React-Native
环境, 因为0.62
更换了CocoaPods
管理iOS
依赖库, 准备先把Android
环境跑通, 首次执行react-native run-android
遭遇滑铁卢, 情理之中, 意料之内.在运行
react-native run-android
后报错如图:
进入路径下对比发现:
分别去了上层目录下对比发现, 很有可能是文件没有下载完整导致, 反复执行react-native run-android
都是没有意义的, 于是删除文件后, 重新执行react-native run-android
等待下载安装依赖包
从终端的输出信息来看, 我的猜想是正确的, 最后对比了下文件正确的样子
-
2020-07-20
安装CocoaPods
依赖库失败, 因为项目使用到了react-native-fast-image
, 这个库是基于SD
的封装,SD
又使用到了libwebp, 在CDN
加持下, 经过一系列依赖库的安装等待后, 迎来了iOS
环境的首个报错:Cloning into '/var/folders/6s/5hf9z6_138v68pqd7v891pd80000gn/T/d20200720-84015-8v2sj1'... fatal: unable to access 'https://chromium.googlesource.com/webm/libwebp/': Failed to connect to chromium.googlesource.com port 443: Operation timed out
通过域名和报错信息也能猜出来啥原因了, 暂时想到两个方案:
- 终端fq
- 修改源
这里采取
方式2
, 修改源的方案
1. 先确认下项目`react-native-fast-image`版本 ~> `8.1.5` 2. `react-native-fast-image`版本依赖的`SDWebImageWebPCoder `版本 ~> '~> 0.6.1' 3. 在本地`pod`源仓库中找到`libwebp`并修改源 默认源: `https://chromium.googlesource.com/webm/libwebp` 替换成: `https://github.com/webmproject/libwebp.git`
换源保存后重新执行
pod install --verbose --no-repo-update
结果失败, 一看错误, 源地址没变, 如果你仔细看过, 在描述文件路径及默认源
这张图中可以发现疑点, 我使用了Trunk
源, 但是改的是Master
中的源地址, 而我podspec
也优先指定了Trunk
源, 所以上一步换源无效, 重新修改对应的源地址后, 执行中验证确认修改成功 到此完成CocoaPods
依赖库安装补充:
关于libwebp
路径我已经在截图中展示了, 没有详细介绍, 可以根据我截图中的路径直接查找, 为了解决复杂的环境及场景, 可以通过find path -iname libwebp
来查找路径:e.g.
shenyj@ShenYj-MBP Desktop % find >/Users/shenyj/.cocoapods/repos/trunk -iname libwebp /Users/shenyj/.cocoapods/repos/trunk/Specs/1/9/2/libwebp
ShenYj.github.io - 简书地址 - 返回首页
-
Apple
Common
蓝牙
LBS
音视频
- AVAudioSessionchange_route
- 切换线路
- StreamingKit
- Audio Unit 基础
OC 与 Swift 混编
Object-C
- 代码混淆
- autoreleasepool
- 忽略编译器(clang)警告
- 定时器
- 锁
- RunLoop
- block
- NS_REFINED_FOR_SWIFT
- NS_CLOSED_ENUM
- NS_TYPED_ENUM、NS_STRING_ENUM
- NS_TYPED_EXTENSIBLE_ENUM、NS_EXTENSIBLE_STRING_ENUM
- 关键字nonnull和nullable
- class、objc_getClass和object_getclass方法区别
- isKindOfClass和isMemberOfClass
- 应用程序的加载
- non-lazy classes & lazy classes
- load方法
- initialize方法
- 方法的本质
- 类型编码
- self和super
- 类的内存分析
Swift
- precondition
- 权限控制
- Array常用Api
- String初始化、定义
- String常用Api
- String截取演练
- Set定义、创建
- Set访问和修改
- Dictionary操作
- Dictionary和KeyValuePairs
- Dictionary与String转换
- 常用高阶函数
- enum原始值
- enum关联值
- enum遍历
- 递归enum
- enum内存分配
- 指针
- for循环
- break跳出循环
- 变量名与关键字冲突
- 类的定义
- 类的继承和初始化
- 关键字: final
- 关键字: mutating
- 关键字: lazy
- 修饰类方法的关键字: static
- 关键字: final、dynamic、objc和_dynamicReplacement
- 关键字:@dynamicMemberLookup和@dynamicCallable
- 关键字: propertyWrapper
- 自定义运算符
- 下标: subscript
- 扩展: extension
- 协议: protocol
- 协议和扩展
- 为什么需要泛型
- 泛型函数定义
- 泛型类型
- 泛型的类型约束
- 关联类型
- 为泛型定义要求
- 泛型下标
- 多线程
- Attributes
- 错误处理
- Codable
- DispatchSourceTimer
- Swift 5.x 演练: 更多功能编辑页
- Swift 5.x 类库收集
- 单元测试笔记
- 实例对象内存结构
- 元类型、Type、Self
- frozen
- convention
- Swift(5.3.2)源码编译
- SQLite.Swift类库演练
- Swift 5.5 关键字: async/await
- Swift 5.5 新特性: Continuations
- Swift 5.5 新特性: Actor
- Swift 方法调度
- Swift Mirror
- Swift 关键字: @_silgen_name
- Swift 关键字: @_disfavoredOverload
- swiftmodule
- Swift 5.6 新特性: Type placeholders
- Swift 5.6 新特性: #unavailable
- Swift 5.6 新特性: CodingKeyRepresentable
- Swift 5.6 新特性: existential any
- Swift 5.7 新特性: if-let/guard 语法简化
- Swift 5.7 新特性: Multi-statement closure type inference
- Swift 5.8 新特性: @backDeployed
- Swift 5.9 新特性: if switch expressions
- Swift 6.0 新特性:@preconcurrency
RxSwift
macOS - AppKit
-
iOS Assembly(ARM64)
-
C++
C++ 基础
- cout、cin
- 函数重载
- 默认参数
- extern "C"
- pragma once
- inline function
- const
- Reference
- 汇编
- 类和对象
- 堆空间内存管理
- Constructor
- Destructor
- 成员变量初始化
- 声明与实现分离
- namespace
- 继承
- 访问权限
- 初始化列表
- 多态:虚函数
- 多态:虚函数实现原理
- 多态:虚析构函数
- 多态:纯虚函数
- 多态:抽象类
- 多继承
- static
- static: 单例模式
- const 成员
- 引用类型成员
- 拷贝构造函数
- 调用父类的拷贝构造函数
- 浅拷贝、深拷贝
- 对象型参数和返回值
- 匿名对象
- 隐式构造
- 编译器自动生成的构造函数
- 友元
- 内部类
- 局部类
- 运算符重载
- 模板
- 类型转换
- C++标准
- Lambda
- 异常
- 智能指针
-
Flutter
Dart
Flutter
-
Go
Go 基础
-
Ruby
Ruby 基础
-
React-Native
React-Native
-
工具篇
-
Swift Package Manager
-
自动化
-
TroubleShooting
-
扩展