基础知识
约 1688 字大约 6 分钟
React Native跨端
2026-04-08
一、React Native 概述
React Native(简称 RN)是 Facebook(Meta)开源的跨端框架,使用 React + JavaScript/TypeScript 编写一次代码,渲染为 原生平台控件(iOS 的 UIView、Android 的 View)而非 WebView,性能接近原生。
与 Flutter 的核心差异
| 维度 | React Native | Flutter |
|---|---|---|
| 语言 | JS/TS | Dart |
| 渲染 | 桥接原生控件 | 自绘引擎(Skia/Impeller) |
| 热重载 | 快速 Fast Refresh | 快速 Hot Reload |
| UI 一致性 | 受原生组件限制 | 像素级一致 |
| 生态 | 极成熟(npm) | 成熟(pub.dev) |
| 原生能力 | 易接入第三方原生库 | 需写 Platform Channel |
二、架构演进:Old vs New Architecture
旧架构(Bridge)
- JS 线程、Native 线程、Shadow 线程通过 Bridge 异步通信
- 所有数据以 JSON 序列化形式传递,存在序列化开销
- 布局用 Yoga(Facebook 开源的跨端 flex 引擎)计算
新架构(2023+ 正式推出)
| 组件 | 作用 |
|---|---|
| JSI (JavaScript Interface) | 允许 JS 直接持有 C++ 对象引用,去掉 JSON 序列化 |
| Fabric | 新的渲染系统,同步优先级调度,和 React 18 并发特性契合 |
| TurboModules | 原生模块的懒加载与类型安全 |
| Codegen | 从 TS 类型定义生成 C++/Java/ObjC 绑定代码 |
| Hermes | 轻量 JS 引擎,启动快、内存小,默认启用 |
新架构要点:Bridge 不再是必经之路,JS ↔ Native 可以直接同步调用,解决动画、手势等对延迟敏感的场景。
三、环境搭建
官方推荐使用 Expo 快速上手,或通过 React Native CLI 获得完整原生工程控制。
Expo(推荐初学)
npx create-expo-app@latest my-app
cd my-app
npx expo start # 扫码在 Expo Go 中预览优势:零原生配置,提供丰富的 SDK(相机、推送、定位等),支持 EAS Build/Update。劣势:部分高度定制的原生库需要 expo prebuild 弹出。
React Native CLI
npx @react-native-community/cli@latest init MyApp
cd MyApp
npm run ios # 需 macOS + Xcode
npm run android # 需 Android Studio需要配置:Node、JDK 17、Xcode、CocoaPods、Android SDK / NDK。
四、核心组件
RN 提供跨平台的基础组件,编译时映射到原生控件:
| RN 组件 | iOS 对应 | Android 对应 | 说明 |
|---|---|---|---|
<View> | UIView | android.view.ViewGroup | 容器 |
<Text> | UITextView | TextView | 文本 |
<Image> | UIImageView | ImageView | 图片 |
<ScrollView> | UIScrollView | ScrollView | 可滚动容器 |
<FlatList> | 虚拟化列表 | 虚拟化列表 | 长列表 |
<TextInput> | UITextField | EditText | 输入框 |
<Pressable> | — | — | 新一代触摸反馈 |
import { View, Text, StyleSheet, Pressable } from 'react-native';
export default function Counter() {
const [count, setCount] = useState(0);
return (
<View style={styles.container}>
<Text style={styles.label}>Count: {count}</Text>
<Pressable onPress={() => setCount(c => c + 1)} style={styles.btn}>
<Text style={styles.btnText}>+1</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, alignItems: 'center', justifyContent: 'center' },
label: { fontSize: 20, marginBottom: 12 },
btn: { paddingHorizontal: 24, paddingVertical: 12, backgroundColor: '#3b82f6', borderRadius: 8 },
btnText: { color: '#fff', fontWeight: '600' },
});五、样式系统
RN 的样式是 JS 对象,使用子集化的 CSS 属性(驼峰命名),不支持 cascade 和伪类。
长度单位
- 无单位数字 = 逻辑像素(density-independent pixels),跨设备一致
- 百分比字符串:
width: '50%' - 获取屏幕尺寸:
Dimensions.get('window')或useWindowDimensions()
Flexbox
RN 的布局引擎是 Yoga,默认 flexDirection: 'column'(与 Web 不同),alignItems、justifyContent 等属性与 Web Flexbox 类似。
<View style={{ flex: 1, flexDirection: 'row', justifyContent: 'space-between' }}>
<View style={{ flex: 1, backgroundColor: 'red' }} />
<View style={{ flex: 2, backgroundColor: 'blue' }} />
</View>StyleSheet vs 内联
StyleSheet.create 会冻结对象并做类型检查,推荐使用。样式库选择:NativeWind(Tailwind CSS for RN)、Restyle、styled-components、Tamagui、Unistyles。
六、导航路由
官方不内置路由,主流库:
React Navigation(最主流)
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Detail" component={DetailScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}提供 Stack / Tab / Drawer / Native Stack 等多种导航器,支持手势返回、共享元素转场。
Expo Router
基于 React Navigation,提供 文件系统路由(类似 Next.js),自动生成类型安全的路由。Expo 项目强烈推荐。
app/
├── _layout.tsx
├── index.tsx -> /
├── user/
│ └── [id].tsx -> /user/:id
└── (tabs)/ -> 分组
├── home.tsx
└── profile.tsx七、事件与手势
- Touchable 系列(旧):
TouchableOpacity/TouchableHighlight - Pressable(推荐):统一抽象,支持长按、状态反馈
- Gesture Handler:
react-native-gesture-handler在原生线程处理手势,性能优于 JS 手势
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
const tap = Gesture.Tap().onEnd(() => console.log('tapped'));
<GestureDetector gesture={tap}><View /></GestureDetector>八、动画
Animated API(内置)
const opacity = useRef(new Animated.Value(0)).current;
useEffect(() => {
Animated.timing(opacity, { toValue: 1, duration: 500, useNativeDriver: true }).start();
}, []);
<Animated.View style={{ opacity }}>...</Animated.View>useNativeDriver: true 将动画交给原生线程运行,避免 JS 线程卡顿。
Reanimated(推荐)
react-native-reanimated 基于 Worklet 在 UI 线程 运行 JS 动画逻辑,帧率稳定:
const offset = useSharedValue(0);
const style = useAnimatedStyle(() => ({
transform: [{ translateX: withSpring(offset.value) }],
}));
<Animated.View style={style} />配合 react-native-gesture-handler 可实现复杂交互动画。
九、列表与性能
- FlatList:内置虚拟化,
keyExtractor必填,getItemLayout可加速 - SectionList:分组列表
- FlashList(Shopify 出品):性能显著优于 FlatList,推荐大型列表使用
性能优化要点:
- 避免匿名函数:
renderItem用useCallback缓存 React.memo:减少子组件无意义重渲染InteractionManager.runAfterInteractions:延迟非关键任务- 图片:用
react-native-fast-image或 Expo Image - Hermes:确保开启 Hermes 引擎
- 开启新架构:Fabric + TurboModules
- Profiling:Flipper(旧)/ React DevTools / Hermes Profiler
十、网络与数据
fetch/axios:HTTP 请求AsyncStorage(@react-native-async-storage/async-storage):异步键值存储react-native-mmkv:腾讯 MMKV 封装,同步读写、性能极高- 状态管理:Redux Toolkit、Zustand、Jotai、Recoil
- 数据请求:TanStack Query(React Query)、SWR
import { useQuery } from '@tanstack/react-query';
function UserList() {
const { data, isLoading } = useQuery({
queryKey: ['users'],
queryFn: () => fetch('/api/users').then(r => r.json()),
});
// ...
}十一、原生模块与三方库
当 RN 官方 API 不满足需求时,可通过 Native Modules 调用平台能力:
// TurboModule 类型定义(Codegen 驱动)
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
getBatteryLevel(): Promise<number>;
}
export default TurboModuleRegistry.getEnforcing<Spec>('BatteryModule');常用第三方库:
react-native-reanimated— 动画react-native-gesture-handler— 手势react-native-screens— 原生屏幕容器react-native-safe-area-context— 安全区域react-native-svg— SVG 渲染react-native-mmkv— 存储react-native-vision-camera— 高性能相机@shopify/flash-list— 高性能列表
十二、应用架构示例
my-app/
├── app/ # Expo Router 路由
├── src/
│ ├── components/ # 通用组件
│ ├── features/ # 按业务模块
│ │ ├── auth/
│ │ └── profile/
│ ├── hooks/
│ ├── services/ # API、原生桥
│ ├── store/ # Zustand/Redux
│ ├── theme/
│ └── utils/
├── assets/
└── app.json十三、发布与 CI/CD
- Expo EAS:
eas build云端构建,eas updateOTA 热更新 - Fastlane:iOS/Android 自动化发布
- CodePush(微软):JS bundle 热更新,已归档但仍可用
- Sentry:错误监控
- GitHub Actions + EAS/Fastlane:完整 CI/CD 管线
十四、React Native 与 React 的差异要点
- 没有 DOM:不能用
div、span、a,改用View、Text、Pressable - 所有文本必须在
<Text>内:否则报错 - 样式不继承:子
<Text>不会继承父<View>的字体(<Text>内部可继承) - 没有 CSS 伪类/媒体查询:用 JS 条件或
Platform.select实现 - Platform API:
Platform.OS === 'ios'、Platform.select({ ios: ..., android: ... }) - 线程模型:JS 线程、Shadow 线程、UI 线程,耗时逻辑不要阻塞 JS 线程
