跳到主要内容

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 后,我们建议从你的 package.json 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 启发的用于可访问性、样式和事件的 props

此版本包含许多受 Web 标准启发的新的 props,以使 React Native 的 API 在多个平台之间保持一致。这些新 props 纯粹是新增的,因此对于等效的可访问性、行为或样式 props,预计不会有迁移或行为改变。

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

注意

有关 React Native 与 Web 标准对齐的更多背景信息,请查看此提案相关讨论

可访问性

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

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

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

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

组件特定行为

还引入了一些 props,以使核心组件的 prop 名称与等效的 DOM prop 名称对齐。

  • ImagealttintColorcrossOriginheightreferrerPolicysrcsrcSetwidth
  • TextInputautoCompleteenterKeyHintinputModereadOnlyrows

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

样式

为了与某些 CSS 样式对齐,以下样式已进行了功能扩展

以下别名已被添加,以覆盖现有的 React Native 样式

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

事件

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

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

  • onPointerOveronPointerOut
  • onPointerEnteronPointerLeave

这些事件也已在 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 的 prop types,例如 ViewPropTypesText.propTypes,在 0.66 版本中被弃用,访问它们会输出弃用警告。当它们在 0.68 版本中被移除时,许多开发者在升级到最新版本的 React Native 时开始遇到错误。

经过一些调查,我们发现有两个问题阻碍了社区对弃用警告采取行动。首先,弃用警告并非总能提供可操作的建议,导致人们忽略它们(问题一问题二)。其次,弃用警告被 LogBox.ignoreLogs 错误地过滤掉了。这两个问题现在都已修复,但我们希望给人们更多时间来升级已弃用的调用点。

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

注意

作为此变更的一部分,我们还从 LogBox.ignoreLog 中移除了控制台过滤功能。这意味着你之前使用 Logbox.ignoreLog 过滤掉的日志在你升级后会再次出现在控制台中。

这是预期的行为,因为它允许发现和修复弃用警告等日志。

开发者体验改进

React DevTools

在此版本中,我们为 React Native 带来了两个流行的 Web 版 React DevTools 功能。

“点击检查”是 React Dev Tools 左上角的一个选项,它允许你点击应用中的一个项目,然后在 Dev Tools 中检查它,类似于 Chrome 的元素检查器。

组件高亮功能会在应用中高亮你在 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 并带来了一些显著改进

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

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

新架构

此版本基于我们目前收集的用户反馈和报告,对实验性的新架构体验进行了许多改进。

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

提醒一下,新架构仍然是一个实验性的 API 体验,我们正在迭代变更以使其更易于采用。请尝试新架构文档中简化的新步骤,并将你的反馈发布到新架构工作组

其他显著修复

  • 更好的堆栈帧折叠:我们更新了 React Native 的内部帧列表,因此 LogBox 将更常显示你的代码,而不是内部 React Native 帧,帮助你更快地调试问题。
  • 构建时间改进:我们将 prefab 资产迁移到了 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 多次提交。

我们特别感谢那些为这些主要的 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 的支持政策