React Native 基础知识

1,084 阅读13分钟

1. React Native 与 React 的主要区别是什么?

React Native 与 React 的主要区别主要体现在以下几个方面:

  1. 渲染目标

    • React 是为 Web 开发而设计的框架,依赖 HTMLCSS 来渲染页面内容。它通过虚拟 DOM(Virtual DOM)来更新浏览器的 DOM。
    • React Native 是用于 移动端(iOS 和 Android)开发的框架,它并不使用 HTML 和 CSS,而是使用原生组件(如 ViewText 等)来渲染内容。React Native 通过将 JavaScript 代码桥接到原生平台来实现与原生 UI 的交互。
  2. 组件和布局

    • React 使用 HTML 元素来构建 UI,比如 <div><span> 等。
    • React Native 则使用封装好的原生组件,比如 View(类似 <div>)、Text(类似 <p>),并且通过 Flexbox 布局来设计界面,没有 HTML 和 CSS 的概念。
  3. 样式

    • React 中,样式是通过 CSSCSS-in-JS(如 Styled Components)来定义的。
    • React Native 中没有直接的 CSS,而是通过 JavaScript 对象来定义样式,使用 StyleSheet.create 方法生成样式对象。
  4. 动画

    • React 中可以使用 CSS 动画、JavaScript 动画库(如 anime.jsGSAP)来实现动画效果。
    • React Native 提供了 Animated APILayoutAnimation API 来实现流畅的动画,并且可以使用第三方动画库(如 React Native Reanimated)来增强动画效果。
  5. 第三方库和插件

    • React 有广泛的 Web 插件和库支持。
    • React Native 提供专门用于移动平台的第三方库,比如 react-native-camerareact-native-geolocation,它们可以访问设备的相机、传感器等功能。
  6. 构建和部署

    • React 主要部署在浏览器上,可以通过各种 Web 服务器提供服务。
    • React Native 需要打包成 iOSAndroid 应用,分别打包为 APK(Android)或 IPA(iOS)格式,并提交到相应的应用商店。
  7. 调试和开发工具

    • ReactReact Native 都可以使用 Chrome DevTools 进行调试,但 React Native 还提供一些移动端特有的调试工具,比如 ReactotronFlipperExpo 等。

总结来说,React 是面向 Web 的前端框架,而 React Native 则是用于跨平台移动开发的框架,它们共享了组件化开发模式和状态管理理念,但在渲染机制、样式定义、动画处理和平台交互等方面存在较大的差异。

2. 解释 React Native 的工作原理。React Native 是如何将 JavaScript 代码转换为原生代码的?

React Native 的工作原理主要依赖于 JavaScript 和原生代码之间的桥接(Bridge)机制,通过桥接来实现 JavaScript 代码和原生平台(iOS/Android)的通信。以下是 React Native 的工作流程及其将 JavaScript 转换为原生代码的方式:

1. JavaScript 线程(JS Thread)

  • React Native 应用的逻辑代码是用 JavaScript 编写的,代码会在 JavaScript 线程中运行。
  • React Native 使用 React 来构建用户界面的虚拟 DOM 树,但在 React Native 中不会像在 Web 上那样直接渲染到浏览器的 DOM,而是构建一个虚拟的组件树,最终与原生组件对接。

2. 原生线程(Native Thread)

  • 在移动平台上(iOS 和 Android),UI 是由平台原生组件控制的。React Native 使用平台特定的渲染引擎,如 UIKit(iOS)或 View 系统(Android)来呈现用户界面。
  • 原生代码会根据 JavaScript 传来的指令,使用原生控件(如 UIViewTextView 等)来完成界面的渲染。

3. 桥接机制(Bridge)

  • Bridge 是 React Native 的核心,它是 JavaScript 和原生代码通信的桥梁。
  • React Native 将 JavaScript 代码与原生平台连接起来,使两者可以互相通信。桥接本质上是一个异步通信机制,用来发送和接收 JSON 格式的消息。
  • 当 JavaScript 线程需要与原生线程通信时,会通过 Bridge 发送消息。消息可以包含用户界面的更新指令或调用原生模块的操作。

4. 通信过程

  • JavaScript 代码触发更新:当用户在应用中执行某些操作(如点击按钮或触发动画)时,JavaScript 代码会将这些交互事件发送给 Bridge。
  • Bridge 转发指令:Bridge 会将这些指令传递到原生端,转化为原生组件的操作(如修改 UI 样式、更新数据等)。
  • 原生端执行操作:原生代码接收到指令后,使用对应的平台组件(如 iOS 的 UIView 或 Android 的 TextView)进行界面更新或其他操作。
  • 数据反馈:如果操作需要反馈数据(如设备的地理位置或传感器数据),原生代码会通过 Bridge 将数据返回给 JavaScript 线程,更新应用状态或触发新的操作。

5. 原生模块和第三方插件支持

  • React Native 支持编写自定义的原生模块,扩展应用的功能。例如,开发者可以用 Java 或 Swift 编写原生模块,然后通过 Bridge 将其与 JavaScript 代码连接,从而在应用中使用平台特定的功能。
  • 这种机制使 React Native 可以灵活地集成第三方插件和库。

6. 优化:JIT 与 Hermes 引擎

  • JavaScript 解释执行速度较慢,为提高性能,React Native 团队开发了 Hermes 引擎,这是一个面向 React Native 优化的 JavaScript 引擎。Hermes 引擎可以对 JavaScript 代码进行提前编译(Ahead-of-Time Compilation),减少代码加载时间,从而提升应用的性能,特别是在启动时。

简单示例:JavaScript 如何调用原生模块

假设应用中需要使用设备的地理位置信息:

  1. JavaScript 调用:JavaScript 代码调用地理位置 API,向 Bridge 发送获取地理位置的请求。
  2. Bridge 传递指令:Bridge 将请求转发到原生代码。
  3. 原生代码执行:原生端获取设备的地理位置(通过 GPS 等),将结果返回到 Bridge。
  4. JavaScript 更新:JavaScript 线程接收到地理位置信息后,更新应用的状态。

总结

React Native 的核心工作原理是 JavaScript 线程与原生线程通过 Bridge 通信,JavaScript 代码负责业务逻辑和组件结构,而原生线程负责渲染 UI。这种设计使得 React Native 应用既能利用 JavaScript 开发的灵活性,又能达到接近原生应用的性能和体验。

3. 在 React Native 中,Virtual DOM 和 Native DOM 有什么不同?

在 React Native 中,Virtual DOMNative DOM 是两个关键概念,它们在工作原理和渲染方式上有很大不同。以下是它们的主要区别:

1. Virtual DOM

  • 定义:Virtual DOM 是一种轻量级的 JavaScript 对象,它用来描述用户界面的状态。React 使用 Virtual DOM 来跟踪 UI 的变化,并决定哪些部分需要更新。
  • 作用:React Native 应用的界面不会直接更新原生视图,而是先在 Virtual DOM 中进行操作。每当应用状态或组件数据发生变化时,React 会创建一个新的 Virtual DOM 树,然后与旧的 Virtual DOM 树进行比较(即 “diffing”)。
  • 工作机制:通过 diffing 算法比较前后的 Virtual DOM 树,React 可以找出变化的部分,并生成更新指令,最终发送给 Native DOM 进行实际渲染。
  • 跨平台:Virtual DOM 是平台无关的,因此可以适应 Web(HTML)和移动端(iOS/Android)的不同平台。

2. Native DOM

  • 定义:在 React Native 中的 Native DOM 是原生平台的视图层,直接由 iOS 或 Android 操控。Native DOM 不是传统的 HTML DOM,而是 iOS 上的 UIKit 组件(如 UIView)、Android 上的 View 系统组件(如 TextView)等。
  • 作用:Native DOM 负责在真实设备屏幕上渲染视图,使用的是各平台的原生 UI 元素。React Native 通过桥接机制(Bridge)将 Virtual DOM 的变化发送给 Native DOM。
  • 工作机制:当 React Native 的 Virtual DOM 检测到某部分需要更新时,会通过 Bridge 发送更新指令给 Native DOM,使其在实际设备上执行界面更新。
  • 性能差异:Native DOM 是基于原生平台的组件,因此渲染速度更快,能够实现流畅的用户体验,但需要由 JavaScript 和 Native 之间的桥接来传递更新,频繁的通信会影响性能。

3. 对比总结

特性Virtual DOMNative DOM
定义用于描述 UI 状态的 JavaScript 对象由原生平台管理的真实视图层
位置在 JavaScript 环境中在 iOS 或 Android 原生应用环境中
更新方式通过 diffing 算法计算出变更,再发送给 Native DOM直接更新原生 UI 元素
平台兼容性与平台无关(适用于 Web 和移动端)依赖于 iOS 和 Android 的原生 UI 组件
通信机制与 Native DOM 通过 Bridge 通信与 JavaScript 代码通过 Bridge 接收更新指令
性能不直接渲染,只负责更新计算直接在设备上渲染,性能更优

总结

在 React Native 中,Virtual DOM 和 Native DOM 是相互协作的,Virtual DOM 管理 UI 状态并计算变更,而 Native DOM 负责具体的原生渲染。React Native 通过 Bridge 将 Virtual DOM 的变更传递给 Native DOM,从而实现接近原生体验的跨平台应用。

4. 如何创建跨平台的样式?有哪些常用的样式组件?

在 React Native 中创建跨平台样式,可以使用平台无关的样式系统。React Native 提供了类似 CSS 的样式规则,但需要通过 JavaScript 对象进行定义,确保同一份代码可以在 iOS 和 Android 上适用。以下是创建跨平台样式的方法及常用的样式组件。

1. 创建跨平台样式的方法

  • 使用 StyleSheet.create:React Native 提供的 StyleSheet.create 方法可以定义和优化样式对象,便于样式的复用和性能优化。例如:
import { StyleSheet } from 'react-native';

const styles = StyleSheet.create({
 container: {
   flex: 1,
   justifyContent: 'center',
   alignItems: 'center',
   backgroundColor: '#F5FCFF',
 },
 text: {
   fontSize: 20,
   color: '#333333',
   textAlign: 'center',
 },
});
  • 使用 Platform 判断平台:可以使用 Platform API 根据不同平台设置不同的样式。例如,在 iOS 和 Android 上使用不同的字体样式:
import { Platform, StyleSheet } from 'react-native';

const styles = StyleSheet.create({
 text: {
   fontSize: 20,
   fontFamily: Platform.OS === 'ios' ? 'Arial' : 'Roboto',
 },
});
  • 利用 Dimensions 获取设备尺寸Dimensions API 可以获取屏幕的宽高,帮助创建响应式样式。例如,根据设备宽度调整布局:
import { Dimensions, StyleSheet } from 'react-native';

const { width, height } = Dimensions.get('window');

const styles = StyleSheet.create({
 container: {
   width: width * 0.9,
   height: height * 0.1,
 },
});
  • 百分比布局和 Flexbox:React Native 支持 Flexbox 布局,可以使用 flexjustifyContentalignItems 创建适应不同屏幕的布局,同时支持宽高的百分比设置。

2. 常用的跨平台样式组件

React Native 提供了一些常用的组件来满足大多数的 UI 需求:

  • ViewView 是最常用的容器组件,用于创建布局。它相当于 HTML 中的 <div>,可以嵌套其他组件并应用布局样式。
<View style={styles.container}></View>
  • TextText 用于显示文本内容。它类似于 HTML 的 <p><span> 标签。Text 组件支持常见的文本样式,如 fontSizecolorfontWeight
<Text style={styles.text}>Hello, React Native!</Text>
  • ImageImage 用于显示图片,支持远程或本地资源。通过 resizeMode 属性可以控制图片的缩放方式。
<Image source={{ uri: 'https://example.com/image.png' }} style={styles.image} />
  • ScrollViewScrollView 是一个滚动容器,可以包含多个子组件并实现垂直或水平滚动。
<ScrollView style={styles.scrollContainer}>
 <Text>Scrollable content</Text>
</ScrollView>
  • TouchableOpacityTouchableHighlight:用于创建可点击的按钮区域,且带有点击反馈效果。TouchableOpacity 是透明点击效果,而 TouchableHighlight 是高亮背景效果。
<TouchableOpacity onPress={() => alert('Button pressed!')}>
 <Text>Press me</Text>
</TouchableOpacity>
  • FlatListSectionList:用于渲染长列表数据,FlatList 是无分组的简单列表,SectionList 则支持分组显示。
<FlatList
 data={dataArray}
 renderItem={({ item }) => <Text>{item.title}</Text>}
 keyExtractor={item => item.id}
/>

3. 样式示例:创建跨平台按钮样式

例如,可以创建一个跨平台的按钮样式:

import { Platform, StyleSheet, TouchableOpacity, Text } from 'react-native';

const Button = () => (
 <TouchableOpacity style={styles.button}>
   <Text style={styles.buttonText}>Click me</Text>
 </TouchableOpacity>
);

const styles = StyleSheet.create({
 button: {
   paddingVertical: 10,
   paddingHorizontal: 20,
   borderRadius: 5,
   backgroundColor: Platform.OS === 'ios' ? '#007AFF' : '#2196F3',
   alignItems: 'center',
 },
 buttonText: {
   fontSize: 16,
   color: '#fff',
 },
});

4. 总结

React Native 提供了跨平台的样式系统和常用组件库,可以帮助开发者高效地创建适应多平台的应用。利用 StyleSheet.createPlatform API、Dimensions、百分比布局和 Flexbox,可以实现更灵活的响应式设计,同时使用常用的组件来构建一致的用户界面。

5. 介绍 Flexbox 布局在 React Native 中的应用及常见的布局技巧。

在 React Native 中,Flexbox 是创建布局的主要工具,提供了一种灵活且响应式的方式来控制组件的排列和大小。以下是 Flexbox 布局在 React Native 中的应用及常见的布局技巧。

1. Flexbox 的基本概念

  • 容器属性:应用在包含子元素的父容器上,决定子元素的排列方向和分布方式。
  • 子元素属性:应用在子元素上,用来调整元素自身的布局。

2. 常用 Flexbox 容器属性

  • flexDirection:决定主轴方向(子元素的排列方向),有以下几种取值:

    • row:水平排列(从左到右)。
    • column:垂直排列(从上到下),这是 React Native 的默认值。
    • row-reverse:水平反向排列(从右到左)。
    • column-reverse:垂直反向排列(从下到上)。
  • justifyContent:控制主轴方向上的子元素的对齐方式。

    • flex-start:从起点对齐(默认)。
    • flex-end:从终点对齐。
    • center:居中对齐。
    • space-between:均匀分布,首尾元素贴边。
    • space-around:均匀分布,首尾元素与边界有等距留白。
  • alignItems:控制交叉轴方向上的子元素的对齐方式。

    • flex-start:从交叉轴起点对齐。
    • flex-end:从交叉轴终点对齐。
    • center:居中对齐。
    • stretch:子元素在交叉轴方向上拉伸以填充父容器。
  • flexWrap:控制子元素是否换行。

    • nowrap:不换行(默认)。
    • wrap:换行,子元素在主轴空间不足时会换行显示。

3. 常用 Flexbox 子元素属性

  • flex:用于定义子元素在父容器中的可用空间的分配比例。

    • flex 值越大,占用的空间比例越大。
    • flex 设置为 1 时,元素会占据所有可用空间。
  • alignSelf:允许子元素在交叉轴方向上覆盖父容器的 alignItems 设置。

    • 可以设置为 auto(继承 alignItems)、flex-startflex-endcenterstretch 等。

4. Flexbox 布局示例

假设要实现一个基本的垂直布局,包含顶部导航、中间内容区、底部栏的三部分布局:

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';

const App = () => (
 <View style={styles.container}>
   <View style={styles.header}>
     <Text>Header</Text>
   </View>
   <View style={styles.content}>
     <Text>Content</Text>
   </View>
   <View style={styles.footer}>
     <Text>Footer</Text>
   </View>
 </View>
);

const styles = StyleSheet.create({
 container: {
   flex: 1,
   flexDirection: 'column',
 },
 header: {
   flex: 1,
   justifyContent: 'center',
   alignItems: 'center',
   backgroundColor: '#f8b400',
 },
 content: {
   flex: 3,
   justifyContent: 'center',
   alignItems: 'center',
   backgroundColor: '#4aa96c',
 },
 footer: {
   flex: 1,
   justifyContent: 'center',
   alignItems: 'center',
   backgroundColor: '#db3069',
 },
});

export default App;

解释:在此布局中,container 作为父容器设置了 flexDirection: 'column',使子元素垂直排列。通过 flex 属性分别设置 headercontentfooter 的高度比例。

5. 常见的布局技巧

  • 均匀分布多个子元素
    • 如果需要让多个子元素均匀分布,可以在每个子元素上设置相同的 flex 值。例如:flex: 1
  • 水平和垂直居中
    • 通过设置 justifyContent: 'center'alignItems: 'center' 实现子元素的水平和垂直居中。
const styles = StyleSheet.create({
 centeredContainer: {
   flex: 1,
   justifyContent: 'center',
   alignItems: 'center',
 },
});
  • 创建左右分布的布局
    • 通过设置 flexDirection: 'row',可以实现水平布局,并使用 justifyContent: 'space-between' 让子元素均匀分布。
const styles = StyleSheet.create({
 rowContainer: {
   flexDirection: 'row',
   justifyContent: 'space-between',
   paddingHorizontal: 20,
 },
});
  • 固定宽度和可变宽度混合布局
    • 有时需要一些固定宽度的组件,比如侧边栏或按钮,可以将 flex 属性留给需要自适应的元素,其他元素设置固定的宽度或高度。
const styles = StyleSheet.create({
 container: {
   flexDirection: 'row',
   height: 50,
 },
 fixed: {
   width: 100,
   backgroundColor: 'lightblue',
 },
 flexible: {
   flex: 1,
   backgroundColor: 'lightcoral',
 },
});

6. 小结

Flexbox 提供了灵活的布局选项,使 React Native 应用在不同设备上都能获得良好的布局效果。熟练使用 flexDirectionjustifyContentalignItemsflexWrap 等属性,可以实现多样化的跨平台响应式布局。

下文预告

《React Native 核心组件和API》

最新最全前端面试文章

微信公众号:【前端大大大】

qrcode_for_gh_c467a0436534_258.jpg