React Native 0.47 正式版发布
2017-08-21 by Marno

本文为【Marno】翻译,原文地址:https://github.com/facebook/react-native/releases
从0.18开始,RN默认项目全面转向ES6,语法大变化,请参考此贴学习 http://bbs.reactnative.cn/topic/15/
如何升级现有项目的RN版本?

  • 本文为 Marno 原创,转载必须保留出处!
  • 公众号【 Marno 】,关注后回复 RN 加入交流群
  • React Native 优秀开源项目大全:http://www.marno.cn

一、导读


这次更新最多的内容就是分包的变化,对性能的优化比较小,因为原理就是那样,无论在怎么优化都不可能突破原生和 JS 之间这道障碍,不过经过这几次不断的分包,代码结构看起来更清晰了,而且随着功能越来越大,也需要这样的方式去优化管理。

这次更新在 Android 增加了对 Kotlin 模块的 link 功能,算是对上次更新遗留问题的弥补,这也说明一个问题,不管你愿不愿意, Kotlin 已经被越来越多的人接受了。

对了,顺便说一下,仔细的人应该早就发现在 Libraries 包下有一个 Experimental 的包,里面包含了一些实验性的组件,包括一些侧滑组件,按钮之类的,感兴趣的可以自己下载源码看下。但是实验性组件,你懂的!

PS:更新有风险,尝鲜需谨慎。个人觉得除非十分必要,否则没有必要经常更新 RN 版本。

二、通用


2.1 重大变化

  • 移除不再使用的 createJSModules 方法(Android)

现在不用特意声明要提供哪个 JS 模块给 native 了,所以将 createJSModule 方法彻底移除了,但是仍可以按照之前的方式来调用 JS 模块。

  • 修正字体 weight 属性的(iOS)

之前设置 weight 的属性值为 “300”或者 “200” ,经过计算后都会按照 Roboto-Thin 样式来处理,这导致这两个值呈现的效果一样,现在已经将这一问题修复。

2.2 修复 Bug

  • VirtualizedList: 修复由于过早调用 _updateCellsToRender 方法带来的问题
  • VirtualizedList: 优化渲染时间计算方式
  • VirtualizedList: 修复当没有设置 getItemLayout 方法时引起的渲染问题
  • CLI: Fix broken default getProjectRoots
  • 修复类文件中声明证书的注释格式(之前只多了个【*号】)
  • Fix deepFreezeAndThrowOnMutationInDev-test for Node v8.1.0
  • 修复 invariant 的引用路径
  • Fix configure glog script when building from xcodebuild
  • 修复在 Geolocation.js 中调用 warning 方法时缺少第一个参数导致的错误

2.3 新特性

  • 在官网的侧边菜单中的 Guides 分类下添加一栏:Components and APIs(改版快主要是将现有组件和 API 进行了分类整理)
  • 添加 marker 来标记整个 native 模块创建的过程
  • 在官网侧边菜单 Guides 下 Images 中添加关于自定义 require 类型的文档介绍
  • 向 RN CLI 服务端添加 https 选项
  • 使 VirtualizedList 支持同一方向的嵌套滚动。
  • Add --maxWorkers flag and allow transformers to run in-band
  • FlatList: 在 Dev 模式下增加对 getItemLayout 返回对象的属性数量的校验,便于我们在开发时能快速定位由于对象缺少属性导致的问题
  • FlatList: 添加 setNativeProps 方法,可以直接对 native 属性进行设置
  • 当同时设置了 pagingEnabled 和 snapToInterval 属性时会报警告
  • 为 SwipeableRow 组件(实验性组件)添加了 close 方法
  • 添加一个新的 babel 转换器用于 inlining regenerator-runtime per file
  • Wix.com 添加到官网的 showcase 中
  • 移除 react-native/packager 文件夹

因为 RN 更换了新的打包工具 metro-bundler,这个工具是 FB 专门为 RN 设计的 JS 打包机,据说比之前用的 packager 更快了,感兴趣的可以到 github 看下,网址:https://github.com/facebook/metro-bundler。

  • Docs:更新了官网中侧边菜单 The Basics 板块中 Handling Touches 下的教程,更便于初学者理解 RN 的 Touch 时间。
  • Docs: 修改了官网侧边菜单一些模块的排序
  • 在尽可能多的地方默认禁用 auto-mock
  • 从 local-cli 中移除 worker
  • Promise support for C++ bridge
  • 给 VirtualizedList 和 FlatList 添加 progressViewOffset 方法,目的为了正确的显示上拉加载动画
  • Implement Systrace integration for Fiber
  • 添加判断 global.performance 确实为空时才进行覆盖
  • 将关于 uglify 和 babel 的类型定义从 React Native 中移到了 Metro Bundler 中
  • 清理 local-cli/core/tests
  • 修复在 Node v8 时使用 mock-fs 造成的问题
  • 修改了之前更新时没有修改到的一些 PropTypes 的引用

记得很多人下载一些开源的项目,运行时会提示 PropTypes 找不到,因为 FB 将 PropTypes 移到了另一个包,所以会找不到,看下之前的更新日志里有提到过的。

  • 改进 <ImageBackground> ,这是上次更新添加的组件,如果不清楚怎么使用,可以看下上次的更新日志。
  • 移除了 retainLines 和 sourceMaps 选项
  • jest、jest-repl、jest-runtime 版本更新到 20.0.4
  • 更新 guidelines
  • 将 preset 变成一个函数来处理不同的开发者设置
  • 将 Native Animated 中 x.__makeNative 的调用调到 super.__makeNative 之前
  • 修改语法,使用 'its' 代替 'it's'
  • Yoga: 如果使用了 flex,那么其总和最小为 1
  • Yoga: 当设置了 display:none 时,停止渲染子节点
  • Yoga: 在 display 属性中添加 flexnone 的属性值
  • ImageBackground: 用 StyleSheet 中缓存的样式代替直接在 style 中设置属性对象,以提高渲染性能。
  • 在文档中添加内容,说明在 Android 上暂不支持keyboardWillShowkeyboardWillHide 属性。
  • 给 debugger.html 添加音频,以保持在 Chrome 中调试 RN 应用时 tab 的优先级
  • 在 react-native 中提供方法获取 unstable_batchedUpdates
  • 当设置了 sticky headers 时禁用子组件 clipping
  • 使用 create-react-class 包中的 createReactClass 取代某些官方组件中的 React.createClass
  • 控制 Metro 是否调用 Babel 去查找 .babelrc 文件
  • 停止在 JSTimers 使用 Map
  • 将 JSTimersExecution 合并到 JSTimers,并删除对 JSTimersExecution 的引用。
  • 允许无参的 rejection 回调
  • 修复 TextInputState 类中 blurTextInput() 方法注释中的错别字
  • 重构了 Button.js 中的代码,使逻辑更清晰
  • 设置 bridge 可以为共享:允许 native 模块在 init 后再注册
  • 使用 prop-types 包中的 PropTypes 代替 react 中的 PropTypes
  • 将 Executor 重命名为 JSExecutor
  • 修改文档中在 Windows 安装开发环境的 choco 命令(缩短语法)
  • 像 app component 添加一个可选的 wrapper component
  • Jest Mocks for NetInfo and Linking
  • 在 Yoga 中检测组件是否溢出

三、Android


修复 Bug

  • 修复 ReactArt 中的绘制弧线计算的问题
  • 修复当没有获取到 Window 权限时程序奔溃的问题
  • 修复 dev 加载指示器
  • 修复 ReactInstanceManager.java 中的 package 顺序

新特性

  • 在文档中指明 Android 目前不支持 overflow: hidden 属性
  • 添加 cmd+opt+ctrl+D 命令以便全局调用 dev menu
  • 添加 dev bundle 下载监听器,方便我们在 bundle 加载的时候可以显示进度,该功能也主要是为了 Expo 显示加载进度的。
  • 为 AndroidViewPager 增加 peeking(偷看) 功能

很多 App 的 banner 都用这种设计,在 Android 上用 ViewPager 实现比较简单,现在官方也正式提供这个属性了。用语言描述的话,大概就是在本页会露出下一页的一边。

  • 在调用同步 native 模块时的错误信息中显示 Java 堆栈信息
  • 在文档中说明如何从 Android 的 asset 目录中读取图片资源 source={{uri: 'asset:/foo.png'}}
  • 控制台 link 命令支持编译用 Kotlin 开发的 Android 模块了
  • 允许添加多个 bridge 监听器
  • 在 ReactInstanceManager.java 类中增加 log 日志打印
  • 移除 SetBuilder 这个类
  • 使用非零的实例化的 key 来标记 INITIALIZE_MODULE 标记
  • 只加载一次核心模块
  • 将代理 server 中标识 host 和 port 的常量分离开,之前IP和端口保存在一个常量中,现在拆分开了。
  • 在 ReactRootView 中调用 removeOnGlobalLayoutListener 时先判断 Android SDK 的版本
  • 将 packages 拆分到 core bridge 和 core RN 中
  • 不再允许 multipart bundle 的传送
  • 将 getConstants 中的 NativeArray 转换成 NativeMap

四、iOS


修复 Bug

  • 修改 iOS 上 WebView 的属性 scalesPageToFit 默认值为 true,该属性表示是否自动放大页面内容以适应浏览器窗口大小
  • OSS build:使用 #import "..." 代替 #import <RCTText/...>
  • 修复在 Apple TV 上的编译错误
  • 修复在开启 JS debugger 的时候不 timer 不Fix timers 不运行的问题
  • 修复在没有 executor 时访问 jsContextRef 造成的奔溃问题
  • 修复调用 AccessibilityManager.setAccessibilityContentSizeMultipliers 时的奔溃问题
  • 修复在 separate bundles 中引用过时资源的问题
  • 修复当组件 height/width 设置为 0.5dp 时会被四舍五入成 1dp 的问题
  • 修复 installGlobalFunction 方法的可见性
  • 将单行 <TextInput> 的 blurOnSubmit 属性默认值设置为 true

新特性

  • 在文档中增加如何获取 iOS 系统版本的说明
  • 根据 Apple 官方指导修改在 iOS 上的蓝色的默认值,从 #0C42FD 改为 #007AFF
  • 使 RCTPackagerConnection 和 RCTSamplingProfilerPackagerMethod
    不再依赖 RCTBridge
  • 修复头文件中使用 CocoaPods/Xcode 导入文件时路径错误的问题
  • 从 OSS React Xcode 项目中移除无用的 folly/File.{h,cpp}
  • 提供 content-available APS key 用于 iOS 静默推送

在 iOS 上如果想要发送一个调静音的推送消息,必须设置 content-available 的值为 1

  • 在 RCTShadowView 中不允许插入子组件
  • 支持 display: none 属性
  • 实现 nativeID 属性以便使 native 代码可以引用 react 管理 views
  • 添加 presentationStyle 属性控制 <Modal> 的表现方式,以便对大屏有更好的支持,如 iPad 和 iPhone7 plus 等
  • 删除不再使用的 RCTRenderingPerf
  • 为 RCTUITextField 增加 editable 属性
  • 将 RCTTextView 中的 placeholderText 属性重命名为 placeholder
  • 增加 RCTBackedTextInputViewProtocol ,以便外部组件访问输入状态
  • RCTTextInput: 将通用的布局相关的逻辑代码移到了基类中
  • 为 <TextInput /> 添加 keyboardType 和 returnKeyType 属性

当用户输入数字的时候,键盘没有提供 Done 或 Enter 按钮,所以增加 returnKeyType 属性,方便我们提供收起键盘的方式,以提高用户体验

  • 允许 RCTModuleData 明确的选择退出执行其创建的主队列
  • 将 RCTAnimation 和 RCTLayoutAnimation 与 RCTUIManager 解耦
  • 新方式去实现 RCTUITextField 的 editable 和 non-editable 属性
  • ScrollView: 添加属性 DEPRECATED_sendUpdatedChildFrames 来控制是否调用 updatedChildFrames 来刷新数据
  • 处理 Chrome debugger 抛出的致命性错误
  • 允许上传视频

之前如果选择相册中的视频进行上传,会读取视频第一帧当作图片上传;现在会判断所选文件的后缀名,如果是 *.mov 则会当作视频上传。

  • 如果 bridge 无效则在 websocket 执行器启动时就报错
  • TextInput: 固定单行 <TextInput/> 的 textWasPaste 属性的返回值为 YES
  • 更新文档中 podspec 集成说明

本文为 Marno 翻译,个人公众号:aMarno,专注分享 React Native 技术

[去论坛发表意见]