跳到主要内容

React Native

React Native 适合放在“已经熟悉 React,但目标不再只是浏览器”的这条线里看。它保留了 React 的组件思维和状态管理方式,但最终渲染出来的是原生平台控件,不是浏览器 DOM。

如果前端团队准备进入 iOS、Android,或者希望一套主要业务逻辑跨平台复用,React Native 基本绕不过去。

先建立一个基本判断

React Native 不是“移动端网页壳”,也不是“小程序换皮”。

它更像是:

  • 用 JavaScript 或 TypeScript 写界面逻辑
  • 用 React 组织组件和状态
  • ViewTextImage 这些组件映射到原生平台控件
  • 在需要的时候接入原生能力和原生模块

官方首页对它的定义很直接:用 React 创建 Android、iOS 以及更多平台的原生应用。官方也明确建议,新项目通常优先配合框架使用,最常见的就是 Expo。

适合什么场景

  • 团队已经熟悉 React,准备进入移动端
  • 业务逻辑、接口层、状态管理希望在多端之间尽量复用
  • 需要真正调用原生能力,而不是只做一个 H5 容器
  • 产品同时覆盖 Android 和 iOS,但原生团队资源有限

不太适合什么场景

  • 强依赖极重原生交互、复杂动画或深度系统集成的应用
  • 团队里几乎没有移动端调试经验,且短期内也不准备补这部分能力
  • 只是想做一个轻量活动页或内容页,这类场景通常 H5 更省事

React Native 到底由哪些层组成

1. UI 组件层

浏览器里常见的是 divspanimg。React Native 里常见的是:

  • View
  • Text
  • Image
  • ScrollView
  • TextInput
  • FlatList

这些组件不是 DOM 标签,而是映射到平台原生 UI。

import { View, Text, Pressable } from 'react-native'

export default function HomeScreen() {
return (
<View style={{ padding: 24 }}>
<Text style={{ fontSize: 24, fontWeight: '600' }}>Hello React Native</Text>
<Pressable onPress={() => console.log('pressed')}>
<Text>打开详情</Text>
</Pressable>
</View>
)
}

2. JavaScript 运行时与打包层

开发时通常会接触这几个名字:

  • Metro:React Native 的打包工具
  • Babel:语法转换
  • Hermes:现在非常常见的 JavaScript 引擎选择

官方无框架启动文档里把 Metro 直接定义成 React Native 的 JavaScript build tool。前端视角理解成“为 React Native 场景定制过的打包器”就够了。

3. 原生桥接与新架构

React Native 这些年最大的底层变化,就是从旧桥接模型逐步转向新架构。

高频会碰到的几个关键词:

  • Fabric:新的渲染系统
  • TurboModules:新的原生模块系统
  • JSI:JavaScript 与原生之间更直接的调用接口

官方架构页把这套内容放在 Fabric、Render/Commit/Mount、Threading Model 这些主题下面。对业务开发来说,不需要先把底层细节啃透,但最好知道一点:

  • 旧架构的通信成本更高
  • 新架构更有利于并发渲染、原生能力接入和性能优化
  • 现在很多库都在逐步对齐这套新架构

Expo 和裸工程怎么选

这是 React Native 入门时最常见的分叉点。

Expo 适合什么情况

  • 希望尽快把项目跑起来
  • 优先要开发体验、调试工具、常见能力封装
  • 大多数需求都能落在 Expo 提供的模块里

裸工程适合什么情况

  • 明确知道需要接入较深的原生能力
  • 团队已经准备维护 iOS / Android 原生工程
  • 现有项目本身就有复杂原生集成需求

一个简单判断是:

  • 先做产品验证、团队初次进入移动端:Expo 通常更顺
  • 项目已经明显进入深度原生集成阶段:裸工程更稳

项目结构通常怎么看

不管走 Expo 还是裸工程,前端同学最关心的通常还是这几层:

  • screens / app:页面
  • components:可复用组件
  • navigation:导航结构
  • services:接口层
  • store:状态管理
  • hooks:业务逻辑复用
  • nativemodules:原生能力接入点

如果项目变大,最好尽早把“页面层”和“业务层”拆开。React Native 项目一旦把页面、请求、状态、设备能力全部糊在同一个文件里,后期维护会非常痛苦。

开发时最常见的几块能力

1. 导航

React Native 本身不规定路由方案。常见做法通常是:

  • Expo Router
  • React Navigation

如果项目走 Expo,新项目直接看 Expo Router 往往更自然;如果是较传统的 RN 项目,React Navigation 仍然非常常见。

2. 状态管理

状态管理思路和 Web React 没本质区别:

  • 局部状态:组件内解决
  • 跨页面共享:Zustand / Redux / Jotai 之类继续可用
  • 服务端数据:更适合交给 TanStack Query 这类数据层

3. 原生能力

真正让 React Native 和普通 React 分家的,通常不是组件语法,而是这些能力:

  • 相机
  • 相册
  • 推送
  • 文件系统
  • 权限申请
  • 蓝牙
  • 地理位置
  • 后台任务

这里一旦进场,问题就会开始变成“iOS 和 Android 行为一致吗”“权限文案够吗”“真机和模拟器一致吗”。从这一步开始,纯前端经验就不够了。

新架构需要关心到什么程度

如果只是业务开发,没必要一上来就钻 Fabric 实现细节,但需要知道三个现实问题:

  1. 依赖库是否支持新架构
  2. 项目当前是否已经切到新架构
  3. 自定义原生模块是否需要按新方式接入

原因很简单。很多“怎么在 React Native 里接某个原生库”的旧文章,默认前提还是旧架构。照着抄不一定能用。

性能问题通常出在哪

React Native 的性能问题,很多时候并不是“RN 天生慢”,而是下面这些地方慢:

1. 长列表

  • 没用 FlatList
  • key 不稳定
  • item 组件渲染过重
  • 图片和测量逻辑太多

2. 重渲染过多

  • 状态边界没拆开
  • Context 放得过大
  • 列表项里塞了太多匿名函数和临时对象

3. 动画方案不合适

  • 用 JS 线程硬顶复杂动画
  • 滚动联动太重
  • 手势和动画没配套设计

4. 图片和资源体积

  • 图片过大
  • 首屏资源加载过多
  • 多端分辨率策略混乱

React Native 项目里,性能问题往往更像“移动端工程问题 + React 渲染问题”的叠加,不是单一层能解释完的。

发布和调试时要有的心理准备

Web 项目改一行代码,刷新浏览器就行。移动端会多出很多现实问题:

  • 模拟器和真机不完全一样
  • Android 和 iOS 不完全一样
  • debug 和 release 行为可能不一样
  • 权限、签名、构建缓存、原生依赖安装都会出问题

所以 React Native 虽然保留了 React 的开发体验,但它始终还是移动端开发,不会真的变成“网页开发平移过去”。

什么时候该选 React Native

可以直接选的情况:

  • 团队主力是 React 前端
  • 目标是 Android / iOS 双端
  • 产品节奏要求快,且原生能力需求在可控范围内
  • 后续愿意接受一定的原生调试和打包复杂度

需要谨慎一点的情况:

  • 应用重度依赖平台特有能力
  • 团队没有人能兜住原生问题
  • 设计目标极度强调平台级细节和极致性能

我的看法

React Native 最有价值的地方,不只是“跨端节省人力”,而是它把 React 这套组件心智真正带进了原生应用开发。

这让前端团队进入移动端时,不至于从零开始。但也别把它想得太轻。只要项目深入到权限、构建、真机调试、原生能力集成,移动端该有的复杂度还是会回来。

如果把它看成“React 团队进入移动端的一座桥”,这个理解通常最准确。