跳到主要内容

React Native 0.71:默认 TypeScript、Flexbox Gap 等...

·13 分钟阅读
Matt Carroll
马特·卡罗尔(Matt Carroll)
Meta 开发者倡导者
Nick Gerleman
尼克·格尔曼(Nick Gerleman)
Meta 软件工程师
Nicola Corti
Nicola Corti
Meta 软件工程师
Lorenzo Sciandra
洛伦佐·夏安德拉(Lorenzo Sciandra)
微软高级软件工程师

今天我们发布 React Native 0.71 版!这是一个功能丰富的版本,包括:

在这篇文章中,我们将介绍 0.71 版的一些亮点。

信息

有关更改的完整列表,请参阅 CHANGELOG.md

默认启用 TypeScript

在此版本中,我们正在投入资源改进 React Native 的 TypeScript 体验。

从 0.71 版本开始,当您通过 React Native CLI 创建新的 React Native 应用时,默认情况下您将获得一个 TypeScript 应用。新项目已配置好 tsconfig.json,因此开箱即用,您的 IDE 将会立即帮助您编写类型安全的代码。

我们还直接从 react-native 包提供内置的、更准确的 TypeScript 类型声明。这意味着您不再需要 @types/react-native,并且类型将与 React Native 版本同步更新。

最后,我们的文档已更新,所有示例都将使用 TypeScript。

注意

升级到 React Native 0.71 后,我们建议从 devDependencies 中移除 @types/react-native

有关此更改的更多详细信息,包括迁移步骤以及这对 Flow 用户有何影响,请参阅我们之前的博文 TypeScript 的一流支持

使用 Flexbox Gap 简化布局

使用 React Native,您可以使用 Flexbox 在不同屏幕尺寸上灵活地布局组件。浏览器已支持 Flexbox 属性 gaprowGapcolumnGap,这些属性允许您指定 Flexbox 中所有项目之间的间距。

这些属性在 React Native 中已被长期 मागणी,0.71 版本增加了对使用像素值定义的间距的初始支持。在未来版本中,我们将添加对更多值(如百分比)的支持。

要了解其用处,请想象一下尝试创建一个具有可变大小卡片的响应式布局,这些卡片之间间隔 10px,并紧贴父容器的边缘。尝试使用子元素的 margin 来实现此布局可能很棘手。

以下显示了一个布局,我们首先为每个子元素设置 margin: 10 样式

Two diagrams. On the left it shows a skeleton of an app with three boxes that have margin around them cause the boxes to have margin around all sides. On the right, the same diagram is shown highlighted to demonstrate the margin on all sides.

Margin 被统一应用于所有子元素的边缘,并且在 Flexbox 中不会折叠,这导致我们在卡片外部有间距,内部的间距是我们想要的双倍。我们可以通过应用非均匀的 margin、在父容器上使用负 margin、将间距减半等方式来解决这个问题,但其实可以变得更简单。

使用 flex gap,可以通过在容器上设置 gap: 10 来实现此布局,从而在卡片内部之间创建 10 像素的间距

Two diagrams. On the left it shows a skeleton of an app with three boxes that have margin only on the inner sides and not the outer sides of the boxes due to the Flexbox gap property. On the right, the same diagram is shown highlighted to demonstrate the margin only on the inner sides.

有关 Flexbox gap 的更多信息,请参阅 CSS Tricks 的这篇博文

面向可访问性、样式和事件的 Web 风格属性

此版本包含一些受 Web 标准启发的新属性,以统一 React Native 在多个平台上的 API。这些新属性纯粹是新增的,因此预计不会对等效的可访问性、行为或样式属性产生迁移或行为变更。

对于引入的任何新属性别名,如果存在一个名称不同的现有属性,并且两者都已指定,则新的别名属性值将优先。例如,此版本为 Image 组件的 source 属性添加了 src 属性别名,以与 Web 上的 src 属性保持一致。如果同时提供了 srcsource,则将使用新的 src 属性。

注意

有关将 React Native 与 Web 标准保持一致的更多背景信息,请参阅此 提案相关讨论

可访问性

我们引入了 ARIA 属性作为现有 React Native 可访问性属性的别名。

这些属性现在存在于 React Native 的所有核心组件上:aria-labelaria-labelledbyaria-modalidaria-busyaria-checkedaria-disabledaria-expandedaria-selectedaria-valuemaxaria-valueminaria-valuenowaria-valuetext

我们还引入了等效的 Web 行为:aria-hiddenaria-liveroletabIndex

有关更多详细信息,请参阅此 issue

组件特定行为

还引入了一些属性,以使属性名称与核心组件的等效 DOM 属性名称保持一致。

  • ImagealttintColorcrossOriginheightreferrerPolicysrcsrcSetwidth
  • TextInputautoCompleteenterKeyHintinputModereadOnlyrows

有关更多详细信息,请参阅此 issue

样式

为了与某些 CSS 样式保持一致,对以下样式进行了功能扩展

已添加以下别名来替代现有的 React Native 样式

有关更多详细信息,请参阅此 issue

事件

最后,我们还添加了一个可选实现的 PointerEvents

启用后,View 上的以下处理程序将支持 hover

  • onPointerOver, onPointerOut
  • onPointerEnter, onPointerLeave

这些事件也在 Pressability 中实现,用于对 hover 的新可选支持。

要启用这些功能,请将以下标志设置为 true

import ReactNativeFeatureFlags from 'react-native/Libraries/ReactNative/ReactNativeFeatureFlags';

// enable the JS-side of the w3c PointerEvent implementation
ReactNativeFeatureFlags.shouldEmitW3CPointerEvents = () => true;

// enable hover events in Pressibility to be backed by the PointerEvent implementation.
// shouldEmitW3CPointerEvents should also be true
ReactNativeFeatureFlags.shouldPressibilityUseW3CPointerEventsForHover =
() => true;
注意

您还需要在 AndroidiOS 原生设置中启用 React 功能标志。

请参阅我们专门的 PointerEvents 博文 以了解更多信息。

恢复 PropTypes

React Native 的 propTypes,例如 ViewPropTypesText.propTypes,在 0.66 版本中被弃用,访问它们会输出弃用警告。当它们在 0.68 版本中被移除时,许多开发者在升级到最新版本的 React Native 时开始遇到错误。

经过一些调查,我们意识到有几个问题阻止了社区对弃用警告采取行动。首先,弃用警告并不总是可操作的,这导致人们忽略它们(问题一问题二)。其次,弃用警告被 LogBox.ignoreLogs 错误过滤。这两个问题现在都已修复,但我们想给人们更多时间来升级弃用的调用点。

因此,在此版本中,我们将重新添加 React Native 的 propTypes,以便人们更容易升级和迁移代码以避免使用它们。deprecated-react-native-prop-types 包也已针对 0.71 版本的所有 prop 进行了更新。未来,我们计划继续弃用并再次移除 prop types。我们预计,当我们重新审查移除时,社区将遇到的问题会大大减少。

注意

作为此更改的一部分,我们还将从 LogBox.ignoreLog 中移除控制台过滤。这意味着您之前通过 Logbox.ignoreLog 过滤的日志在升级后将开始再次出现在控制台中。

这是预期的,因为它允许找到并修复弃用警告等日志。

开发者体验改进

React DevTools

在此版本中,我们已将 Web 上的两项流行的 React DevTools 功能引入 React Native。

"Click to inspect" 是 React Dev Tools 左上角的选项,它允许您点击应用中的某个元素,以便在 Dev Tools 中检查它,类似于 Chrome 的元素检查器。

Component highlighting 将突出显示您在 DevTools 中选择的元素在应用中,这样您就可以看到哪些 React 组件与屏幕上的哪些元素相对应。

以下是这两种功能的实际演示

Video of the behavior described above in action. On the left is a React Native app running in an iPhone simulator. On the right is the React DevTools. In both workflows, clicking on an item in the DevTools highlights the corresponding components in the app.

Hermes

在 React Native 0.70 中,我们已将 Hermes 设置为 React Native 的默认引擎

在 React Native 0.71 中,我们升级了 Hermes,并带来了一些显著的改进

  • 改进源映射:通过 Metro 在网络上加载源映射,我们在 Flipper 之外的 Chrome Dev Tools 的最新版本中恢复了使用源映射的能力。
  • 改进 JSON.parse 性能:此版本包含一项性能优化,可将 JSON.parse 的性能提高多达 30%。
  • 添加对 .at() 的支持:Hermes 现在 支持 StringTypedArrayArray.at()

有关更改的完整列表,请参阅 Road to 71 issue

新架构

此版本根据用户反馈和我们迄今为止收集的报告,为实验性新架构体验带来了许多改进。

  • 减少构建时间:新的分发模型使用 Maven Central,这使我们能够大大缩短 Android 的构建时间,解决了 Windows 上的许多构建问题,并为新架构提供了更无缝的体验。在此处阅读更多
  • 编写更少的 C++ 代码:您现在可以启用新架构,而无需在应用中添加任何 C++ 代码,并且 CLI 应用模板已删除所有 C++ 代码和 CMake 文件。在此处阅读更多
  • 更好的 iOS 应用设置封装:在 iOS 上,我们采用了与 Android 类似的方法,并将新架构设置的大部分逻辑封装在 RCTAppDelegate 类中,这将通过更少的手动破坏性更改来简化未来的升级。
  • 更好的 iOS 依赖管理:对于库维护者,我们添加了一个新的 install_module_dependencies 函数,可以在您的包 podspec 中调用,该函数将安装新架构所需的所有依赖项。
  • 错误修复和更好的 IDE 支持:我们修复了用户在新架构工作组中报告的多个错误和问题(例如 Android 的更好 IDE 支持)。

提醒一下,新架构仍然是一个实验性 API 体验,因为我们正在不断改进以简化采用。请尝试 新架构文档 中简化的新步骤,并将您的任何反馈发布到 新架构工作组

其他值得注意的修复

  • 更好的堆栈帧折叠:我们更新了 React Native 的内部帧列表,因此 LogBox 将更多地显示您的代码而不是内部 React Native 帧,从而帮助您更快地调试问题。
  • 构建时间改进:我们将资产迁移到 Maven Central 以进行预制件,以改善当前和新架构中 Hermes 的构建时间(iOS 和 Android)。
  • Android 模板改进:Android 模板得到了大量清理,现在完全依赖于 React Native Gradle 插件。您可以在模板内部或在 网站上的新专用页面 中找到配置说明。

重大变更

  • 控制台日志记录更改:LogBox.ignoreLog 不再过滤控制台日志。这意味着您将在控制台中看到您在 LogBox 中已静音的日志。有关更多详细信息,请参阅 此评论
  • 移除了 AsyncStorage 和 MaskedViewIOS:这些组件自 0.59 版本起已被弃用,因此是时候将它们完全移除了。有关替代方案,请查看 React Native Directory,其中包含涵盖这些用例的社区软件包。
  • JSCRuntime 移至 react-jsc:react-jsi 现在分为 react-jsc 和 react-jsi。如果您使用 JSCRuntime,则需要将 react-jsc 添加为依赖项(facebook/react-native@6b129d8)。

致谢

此版本得益于 70 多名贡献者贡献的 1000 多个 commit。

我们特别感谢对以下主要 React Native 项目做出贡献的人员

最后,感谢 @cortinico@kelset@dmytrorykun@cipolleschi@titozzz 完成此版本!

立即尝试 0.71.0!

对于 React Native CLI 用户,请参阅 升级文档,了解如何更新现有项目,或使用 npx react-native init MyProject 创建新项目。

React Native 版本 0.71 将在 Expo SDK 版本 48 中支持。

信息

0.71 现在是 React Native 的最新稳定版本,0.68.x 版本已不再支持。有关更多信息,请参阅 React Native 的支持政策