React Native 0.48 正式版发布
2017-09-30 by Marno

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

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

一、导读


翻译更新文档真是一件特别枯燥无聊的事情,还会占用大量的业余时间,但是为了翻译的尽量准确,我会详细查看每一个更新的内容,然后结合修改的代码和更新说明再进行翻译。尽管如此有时候还是可能出现翻译的不太准确的地方,希望大家可以谅解。如果发现有翻译不准确的地方,可以通过留言或者关注我的公众号联系我进行修改。

这次更新对 iOS 的变动要大一些,新增了一个组件<MaskedViewIOS>,还在
Guides (IOS) 中添加了 App Extensions 相关的内容,具体使用可以到官网看下。还有就是大量重构了 TextInput 相关的代码,合并了很多属性,除此之外还为适配 iOS11 做了一些改动,具体可以看详细的更新日志。

二、通用


2.1 重大变化

  • 使 RCTDeviceEventEmitter 报致命性的警告

之前如果 RCTDeviceEventEmitter 中出现错误,会通过 console.warn() 方式来提醒,现在如果发生错误,会直接通过 throw new Error() 方式抛出错误。

  • 移除 RCTUIManager.h 文件中 3 个不再使用的通知(iOS)

  • 移除了官方 APIs 中的 AdSupportIOS(iOS)

官方解释是为了集中精力提供更多高质量的组件,会逐渐移除那些不属于该范畴内的一些 API 和 Component。但是如果你的项目中用到了该组件,可以继续从 react-native-deprecated-modules 中引用该组件(以往移除的一些组件也都可以在这里找到),或者使用后面推荐的这个库来代替: https://github.com/ptomasroos/react-native-idfa/

2.2 修复 Bug

  • 修复 JSClassCreate 的错误调用
  • 修复由于解决 #14684 问题时无意间引起的副作用

之前在解决 SwipeableRow.js 与 react-navigation 的手势冲突时,导致了一个黄盒警告,现在已经解决了。记得之前有提到过 SwipeableRow 这个组件,是一个实验性组件,想了解的可以翻下 0.47 的更新日志

  • 修复 CLI 中缺少 "getPolyfills" tag 的问题
  • 修复 <ImageBackground> 不能正常嵌套在 <TouchableXXX> 组件中的错误
  • Yoga: Fixing edge case issue in Yoga where text node was unnecessary rounded down
  • Yoga: Reset the hadOverflow flag at the beginning of the algorithm
  • Docs: 修复 Linking.js 注释中的拼写错误
  • Docs: 修复 Animations.md 中的拼写错误
  • Docs: Fix mistake acquireWakeLockNow in headless js section
  • Docs: 修改 <SectionList> 组件的文档中的示例代码

之前版本的示例代码让人以为 title 是 section 的必须字段,但实际上不是,所以在文档的示例代码中删除了
title 字段。

  • Docs: 修改<StatusBar> 组件的 backgroundColor 属性的值类型为 string
  • Docs: 修复文档中不完整的链接地址
  • Docs: Fix navigation menu regression on mobile
  • Docs: 修正 FlatList.js 类注释种的语法错误
  • Docs: 修改文档中不规范的缩进

2.3 新特性

  • 为 WebSocket 添加 Blob 实现 ,使 WebSocket 支持二进制数据的传递
  • __fbBatchedBridge is undefined 的报错信息中添加可能导致该错误出现的原因
  • 添加缺少的 assetRegistryPath 命令到 dependencies command
  • 为 Animated.spring 添加一个 delay 属性,以推迟动画的开始时间
  • 为 TouchableHighlight 启用 flow
  • 将 KeyboardAvoidingView 组件中的属性抽取到了ViewPropTypes.js 中统一管理
  • application/javascripttext/javascript 都添加为 packager 支持加载的 bundle 的类型
  • 添加 CODEOWNERS 文件方便自审查 PR 的代码
  • 移除了一些不再使用的 npm 依赖库,并且添加了一个 babel-plugin-transform-flow-strip-types 的新依赖
  • 将所有文件中的 React.createClass 替换成 create-react-class 包中的 createReactClass 方法

之前的版本更新中就已经将 React.createClass 移除了,所以大家有用到 React.createClass 的,或者下载的三方库中有用到的,记得去替换下。

  • SwipeableRow: 添加属性可设置禁用左滑或者右滑的事件,以解决和 react-navigation 滑动返回的冲突
  • VirtualizedList: 调整了 getItemLayout 的临界值,使列表可以滚动到最后一项
  • 在 Linux 平台上添加支持通过 chromium 使用 devTools 进行 RN 应用调试
  • 将 polyfills 重新移回到 react-native 中
  • 修改了 PushNotificationIOS 组件中拼写错误的属性名
  • 将 throat 依赖从 3.0.0 更新到 4.1.0
  • 将 inspector proxy 从 packager 移走
  • 在 ReactNativeART.js 避免反复创建新的 Path 示例导致性能降低
  • 将 runServer.js 中的 polyfills 改为 getPolyfills() 以提高可配置性
  • 尝试将 React DevTools 主题和现在 Nuclide 主题统一
  • 将 Jest 版本从 20.1.0-alpha.3 更新至 20.1.0-chi.1
  • 在 CLI 命令行工具中添加了 info 命令,可以显示 react-native 相关信息,使用方法为:react-native info
  • 移除 TouchableOpacity 组件中与 focusedOpacity 相关的属性和方法
  • 移遗留的 JSC profiler
  • 将 Flow 从 0.49.1 更新到 0.50.0 版本
  • 移除 metro-bundler 中默认的 polyfills
  • 设置值时停止 native 驱动的动画
  • 更新 metro-bundler 版本从 0.9.0 到 0.10.0
  • 将 transform 速度提高 8.5%
  • 将 RCTDevMenu.m 中的 Hide/Show Inspector重命名为 Toggle Inspector
  • 在核心代码初始化时使 Set 和 Map 懒加载
  • 统一了 NetInfo API 在两个平台上的返回字段,并且提供方法判断当前连接的网络频段是 2g/3g/4g
  • 移除了 ScrollView 组件中的 onScrollAnimationEnd 属性
  • 将 JSTimers 的 requires 设为内联方式
  • 为不同平台下的 View props 添加 hook
  • 移除 JSCTracing.cpp 中不再使用的 nativeTrace*stage 方法
  • 在 runServer.js 中添加属性和方法,用来控制 Metro 是否通过 Babel 去查找 .babelrc 文件
  • 为 MessageQueue.spy 输出的日志信息多添加了一些信息
  • Docs: 修复了 StatusBar 组件文档中某些属性锚点链接跳转不正确的问题
  • Docs: 修改 Navigation.md 文档,将 NavigatorIOS 的 push 方法所接收的参数类型变成 route 对象,并为其添加 passProps 属性
  • Docs: 修改 Headless 文档,添加如何传递参数的示例代码
  • Docs: 在 Performance.md 文档中说明, Animated API 默认在 JS 线程进行计算,但设置了
    useNativeDriver 属性后则会在 Native 线程计算(这也是提高动画流畅度的一种方式,感兴趣可以搜一下,网上有相应的文章)
  • Docs: 修改 IntegrationWithExistingApps.md 文档中示例代码中的项目名称,旧版本中前后名称不一致,init 时使用的是 MyReactNativeApp ,但是注册的时候使用的是 HelloWorld
  • Docs: 更新 Transforms 的文档,标明了哪些属性已经过期;并且对各属性的值类型做了说明,标明哪些需要传入 string,哪些需要传入 number
  • Docs: 为 <Modal> 设置 animationType 属性时传入的值不用再使用 {} 包裹
  • Docs: 将 ReactImageView 中 setSrc() 方法的参数由 String 改为 ReadableArray
  • Docs: 在文档中明确说明了 FlatList 继承了所有 ScrollView 的属性
  • Docs: 给 TouchableWithoutFeedback.js 中的 onPressIn 和 onPressOut 属性添加说明
  • Docs: 更新 podspec 集成说明,在 >=0.47 的版本中需要引入 CxxBridge
  • Docs: 在 ListView 的文档中添加了一些使用说明,具体如下:
  1. 在水平的 ListView 中 header 和 footer 是如何渲染的(header在左,footer 在右)
  2. 添加如何使用 cloneWithRowsAndSections 的示例代码
  3. 为 getRowCount() 和 getRowAndSectionCount() 方法添加说明
  • Docs: 之前添加了 <ImageBackground> 组件后没有更新 Image 文档中相关的说明,这次将这部分说明及示例代码都更新了
  • Docs: 澄清了如果在 OC 代码中的类以 RCT 为前缀,在 JS 层调用的时候应该排除掉前缀。
  • Docs: 澄清在 Android 平台上 ScrollView 的 pagingEnabled 仅支持横向

之前的文档没有误让人以为 pagingEnabled 在双平台都支持横向、竖向模式,但其实在 Android 上不支持竖向模式。

  • Docs: 为 <Image> 组件增加示例代码,说明如何通过 'data' 来展示图片
  • Docs: 修改侧边菜单 IntegrationWithExistingApps.md 中示例代码的项目名称
  • Docs: 将示例代码中通过 pod 导入文件的路径改为单引号包裹
  • Docs: 在 sectionList 中尽管·1使用了 keyExtractor 方法,仍需要单独为整个 section 设置 key
  • Docs: 将 Animated 添加到 ComponentsAndAPIs 栏目的 Others 分类下
  • Docs: 为 ScrollView.js 中的 onMomentumScrollEnd 属性添加说明文档
  • Docs: 为 ScrollView.js 中的 onMomentumScrollBegin 属性添加说明文档

三、Android


修复 Bug

  • 修复在使用某些角度旋转图片时使其边缘产生锯齿的问题
  • 修复当调用图片剪裁时给 displaySize 属性设置 float 类型的值时导致的奔溃
  • Fixed new line and prioritise blurOnSubmit in multiline text input
  • 修复 HEAD 请求方式失败的问题
  • 修复当初始化后再去更新 z-index 属性无效的问题
  • 将 WebSocket 模块中接收到的二进制消息转换为 base64 而非 utf-8 格式

新特性

  • 在 Headless JS 文档中添加说明,提示用户记得将 service 添加到 AndroidManifest 中
  • 将 ReactWebViewManager.java 类中的方法和变量的权限修饰符由 private 改为 protected
  • 支持为 ARTSurfaceView 设置背景色
  • 为 Arguments.java 类中添加了一些新功能,具体如下

1.添加了 ReadableArray 转换成 ArrayList 的方法
2.添加了 List 转换成 WritableArray 的方法
3.修改了 toBundle 方法,使其支持 arrays
4.修改了 fromBundle 方法,使其支持 lists

  • 在 DrawerLayoutAndroid 文档中添加如何调用 openDrawer 和 closeDrawer 方法的说明
  • 将 Native Modules Android 文档中涉及到的 ToastAndroid 名字换成 ToastExample

在该文档中所说的 ToastAndroid 并非 API 中提供的那个,而只是为了演示 Android 原生 Toast 如何使用而创建的名字,所以为了避免混淆,干脆将其改名为 ToastExample。

  • 简化 MethodInvoker.cpp 中的宏的使用
  • 升级了 Fresco 相关依赖的版本(从1.0.1 > 1.3.0 )
  • 剧烈摇晃手机 2 次后显示 DevMenu
  • 在 drawable 加载完成后再进行 ToolbarAndroid 布局
  • 将 ReactInstanceManagerBuilder.java 类中的成员变量由 protected 变成 private
  • 为 CxxModule.h 中的 getConstants 方法提供默认实现
  • 删除 settings.gradle 文件中已经不存在的 module 的引用
  • 在清理内存缓存前先检查 fresco 是否完成初始化
  • 将 window 的尺寸和屏幕 orientation 区分开

在某些情况下,设备是竖屏的,但是获取到的 window 的尺寸却是横屏的尺寸,这是因为当设备方向发生变化时,尺寸更新事件从 ReactRootView 获取到了错误的尺寸。现在将 window 尺寸和 screen 尺寸拆分开,就不会发生这样的情况了。

四、iOS


修复 Bug

  • 修复 legacy React bridge 中的 build-break
  • 修复因为使用不支持的设备方向 event 而导致的奔溃
  • 修复拼写错误,之前将 UIKit 写成了 UIKIt
  • 修复 RCTNetworking 错误信息
  • 修复字体 weight 属性分辨率
  • 修复当使用 <ImagePickerIOS> 组件选择的照片没有 orientation 信息的问题
  • 修改 RCTDevSettings.mm 种的语法错误
  • 修复当使用 UIDeviceOrientation 时 tvOS 的构建问题

新特性

  • Podspec: 添加所需的 "DevSupport" 依赖 "InspectorInterfaces.{cpp,h}
  • 添加代理 hook 以提供不同的 JS 实现
  • 为 builds 添加 FORCE_BUNDLING、SKIP_BUNDLING 标记来区分是真机还是虚拟机
  • 为 ScrollView 添加 contentInsetAdjustmentBehavior 属性来适应 IPhone X 的“刘海”
  • 移除不再使用的 RCTDebugComponentOwnership.js
  • 移除过时的 RCTAssert 别名
  • RCTCxxBridge.mm 中的 [RCTConvert folly_dynamic:] 直接更名为 convertIdToFollyDynamic
  • 为 ViewManager 添加继承支持

在 Android 已经早就支持继承来扩展功能,但是 iOS 还没有,所以之前想要自定义 ViewManager ,只能自定义一个,然后复制之前的代码,再把自己扩展的代码加上。

  • 新增组件 MaskedViewIOS:可以为组件添加一个透明的遮罩
  • Generalize/refactor -[RCTUIManager rootViewForReactTag:withCompletion:]
  • RCTScrollEvent: get all required values injected rather than accessing the scroll view
  • 引入 RCTBackedTextInputDelegate 用于管理 RCTTextField 和 RCTTextView 相同的代码
  • ScrollView: 从 RCTCustomScrollView 中移除多个不必要的逻辑检查
  • 将 RCTUIManager.m 中的 RCTAssertThread 和 RCTAssert 统一替换为 RCTAssertUIManagerQueue 方法
  • 传递实际加载的图片尺寸用于加载

<Image>组件加载图片时,可以在 onLoad 回调方法中获取图片的大小,但是这一方法在 iOS 上经常不能正确的回掉真实的图片尺寸,现在对这一回调进行了优化。

  • 在 RCT_DEBUG 模式下使 js 堆大小为之前 2 倍
  • 简化 RCTModuleMethod 中的 processMethodSignature
  • 从 RCTRootView 中移除无用的 _launchOptions
  • 使用 Apple 发布的有显著变化 API

这里主要是对定位权限的一些修改,以适应 iOS11 的体验

  • 添加对 namedOrientationDidChange 支持
  • RCTCxxBridge: 使用 C++ atomic
  • RCTImage: 使用 C atomics 代替 OSAtomic
  • RCTProfile: 使用 C atomics 代替 OSAtomic
  • 显示 bundle 传送到手机上的进度,此进度并不是之前已经有了的 packager 转换的进度
  • 通过 packager 对 bundle 的内容类型进行验证
  • 在 CameraRoll 添加属性支持获取其中视频的持续时长
  • TextInput:将 setSelection 方法提取到基类中
  • TextInput:将 RCTTextField.m 和 RCTTextView.h 中的多个属性统一提取到了 RCTTextInput.m 中

主要包括 blurOnSubmit、clearsOnBeginEditing、clearTextOnFocus

  • TextInput: 为了更好的解耦,已将与 textInputDidChange 相关的代码移到了适配器中
  • TextInput: 实际的 reactAccessibilityElement 实现
  • TextInput: 统一了单行和多行输入文本中的 selection 属性,并且完善了 selection 事件的处理
  • TextInput: 将 textInputShouldEndEditing 和 textInputDidEndEditing 移到了基类中
  • TextInput: 简化 selectTextOnFocus 内部逻辑
  • TextInput: 精简 contentSize 计算方式
  • ScrollView/TextInput: 将滚动区域限制到有内容的区域
  • ScrollView: 使用自动调整尺寸的 masks 进行 UIScrollView 的实际布局
  • ScrollView: 更智能的保持 contentOffset

之前当 ScrollView 在竖屏状态下滚动到最后一项时,将设备旋转至横屏,ScrollView 并不会停留再最后一项,这个 PR 就修复了这个问题

  • 为 WebView 的 window.postMessage 添加队列机制,不会让两个时间特别接近的事件发生丢失
  • 支持 shadowView.rootView
  • 为 Apple TV 的 RN 项目添加 Cocoapods 支持
  • Debugger 信道消息应该只在后台线程中进行处理
  • 使用静态方法代替部分 export 导出的方法
  • 将非外部的 string 变量标记为 static
  • CameraRoll: 使用 C atomic 代替 OSAtomic
  • 更高效的动态 ->NSString 转换
  • 降低网络连接错误的日志级别
  • Apple TV: 添加在遥控器长按播放键打开 dev 菜单的功能
  • 统一修改工程中 tab 缩进为两个空格
  • Docs: 更新了 Native UI Components 中与地图组件相关的说明和示例代码
  • Docs: 添加了 App Extensions 相关文档,指导开发者在手机通知栏中添加部件

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

[去论坛发表意见]