React Native 最近有个令人兴奋的消息——V0.74 版本在几天前发布了,包含了超过1600个提交。亮点如下:
- Yoga 3.0
- 新架构:默认无桥模式
- 新架构:批量 onLayout 更新
- 新项目使用 Yarn 3
下面我们深入了解每个新亮点。
Yoga 3.0
首先了解一下 React Native 中的 Yoga 是什么。
Yoga —— 布局引擎
Yoga 是一个由 Meta 开发的开源布局引擎。它负责在用户界面内排列和定位 UI 元素(如按钮、文本、图像等)。
Yoga 为每个 UI 元素计算以下四个方面:
- 定位
- 尺寸
- 对齐
- 间距
通过 Yoga,你可以创建响应式布局,适应不同的屏幕尺寸和方向。它还在 React Native 中实现了一个广泛使用的概念——CSS Flexbox。因此,Yoga 可以说是 React Native 灵活 UI 的核心。
Yoga 3.0 —— 新特性
在之前的所有 React Native 版本中,存在一些不正确的布局行为。Yoga 3 解决了这些问题。其中一个最常见的问题是 ‘row-reverse’ 样式无法正常工作。
来看下图,左边是 V0.73,右边是 V0.74。
在上图中,我们有一个 <Container />,内部是一个 <Parent /> 组件,再内部是两个 <Child /> 组件。
我们在 <Parent /> 组件中应用了如下样式:
// <Parent /> 组件的样式
style={{
flexDirection: 'row-reverse',
backgroundColor: 'dodgerblue',
flex: 1,
marginLeft: 100,
marginRight: 20,
marginVertical: 20,
alignItems: 'center'
}}
你注意到了吗,我们为 <Parent /> 添加了 100 像素的 marginLeft?是的,但看下 React Native V0.73(左边)的输出。它显示右边有 100 像素的边距(而不是左边)!!现在看下 React Native V0.74(右边)的输出。很好,在 V0.74 中,我们看到左边有了完美的 100 像素边距,并且两个 <Child /> 组件也被反转了 🚀。
所以,在 Yoga-2 中,如果你在组件上应用了 ‘row-reverse’ 的 flex-direction 以及 “margin” 或 “padding” 或 “border”,那么该组件的边缘也会被翻转。但在 Yoga-3 中,这个问题已经完美解决了 💯。
Yoga-3 还带来了一些 Yoga-2 中缺失的重要样式组件:
- alignContent 样式的 space-evenly 属性。
- position 样式的 static 属性。
新架构:默认无桥模式
旧架构
React Native 以前使用桥来在 JavaScript 和原生模块之间通信。这些模块用 C++、Objective C、Java 或 Kotlin 编写,以访问摄像头、传感器等原生功能。不幸的是,桥有一些限制。
一个主要限制是,每次一个层与另一个层通信时,都涉及序列化(将 JS 对象转换为 JSON 字符串)和反序列化(将 JSON 字符串转换回 JS 对象)数据。由于转换需要时间,这个过程会给通信流程带来性能问题。
新架构——性能提升
好消息是,React Native 团队能够用一个叫做 JSI(JavaScript 接口)的接口替换桥。它用 C++ 编写,使所有原生功能都可以通过你的 JS 代码访问,这意味着你可以调用原生方法而无需数据序列化或反序列化,使应用程序超级快速。
移除旧架构依赖
JSI 是新架构的核心部分。为了在我们的应用程序中充分启用 JSI(新架构),我们需要先移除应用程序对旧桥架构的依赖。为此,React Native 团队引入了新架构的三个支柱,使我们能够完全摆脱对桥的依赖。
- TurboModules:移除了应用程序对桥中原生调用的依赖(在 V0.68 中发布)。
- Fabric Renderer:移除了应用程序对桥中组件渲染的依赖(在 V0.68 中发布)。
- Bridgeless Mode:移除了应用程序对桥中其他部分(如错误处理、全局事件发射器、计时器等)的依赖(在 V0.73 中发布)。
V0.74 中的新特性
从 V0.74 开始,一旦你启用了新架构,你会看到“无桥模式”已自动启用。然而,新架构本身默认仍未启用。
当你在 V0.74 中启用新架构时,你会在 Metro 日志中看到如下两行:
这就对了 🚀。从 React Native V0.74 开始,启用新架构后,无需手动启用无桥模式 💯。
新架构:批量 onLayout 更新
另一个好消息是,React Native 团队不仅将新架构的无桥模式设为默认,还改进了此架构,以处理批量 onLayout 更新(在单个渲染中执行多个更新)。这种优化通过减少渲染期间的布局相关计算来提高性能。
“onLayout” 属性
React Native 中的 onLayout 属性用于处理组件的布局(位置)变化。当组件的布局发生变化(由于挂载、调整大小、旋转或其他因素)时,onLayout 回调函数会被触发。
你可以像下面这样使用这个属性,根据更新的布局信息执行操作。
function App(){
return (
<View
notallow={() => {
console.log('Component has been invoked 🚀')
}}
/>
)
}
“onLayout” 批量更新如何工作?
假设组件 <App/> 如下所示,每个 View 在挂载时触发 onLayout 回调函数。
function App() {
const [state1, setState1] = useState(false)
const [state2, setState2] = useState(false)
const [state3, setState3] = useState(false)
console.log('✅ COMPONENT RE-RENDERED .....')
return (
<View>
<View
notallow={() => {
console.log('FIRST View invoked')
setState1(true) // View 挂载时更新 state1
}}></View>
<View
notallow={() => {
console.log('SECOND View invoked')
setState2(true) // View 挂载时更新 state2
}}></View>
<View
notallow={() => {
console.log('THIRD View invoked')
setState3(true) // View 挂载时更新 state3
}}></View>
</View>
)
}
现在,在 React Native V0.73 中,你会看到如下输出 👇。
每次执行 onLayout 回调时都会重新渲染整个组件。
在 React Native V0.74 中启用新架构后的输出 👇。
性能惊人🔥。在执行所有 3 个 “onLayout” 回调时,组件只重新渲染了一次。
关于 “onLayout” 批量更新的总结如下图 👇。
新项目使用 Yarn 3
Yarn 3 现在是通过 React Native Community CLI 初始化的新项目的默认 JavaScript 包管理器。它取代了已被弃用且之前用作默认的 Yarn Classic(1.x)。
Yarn 3 加快了安装和更新依赖项的过程,并优化了依赖项的存储方式。
结论
React Native 版本 0.74 在组件布局、架构、批量 onLayout 更新和与 Yarn 3 的集成方面引入了重要改进。