🌱 RN 从零到一(一):React Native 是什么 — 用 React 写原生应用
系列导读:这是「RN 从零到一」系列的第 1 篇。React Native 是 Meta(Facebook)开源的跨平台移动开发框架, 用一套 React + JavaScript/TypeScript 代码同时构建 Android 和 iOS 原生应用。
本文目标:理解 React Native 的定位和原理,完成环境搭建,创建并运行第一个 App。
📊 React Native 速览
| 维度 | 说明 |
|---|---|
| 🏢 出品方 | Meta(Facebook),2015 年开源 |
| 🎯 定位 | 跨平台原生移动应用开发框架 |
| 📝 开发语言 | React + TypeScript(推荐) |
| 📦 当前版本 | 0.76+(新架构已默认启用) |
| 🌐 支持平台 | Android / iOS(社区支持 Windows / macOS / Web) |
| ⭐ GitHub Star | 120k+ |
| 🏗 架构 | 新架构(Fabric + TurboModules + JSI) |
🧩 为什么选 React Native?
跨平台开发的痛点
传统做法:Android 和 iOS 各写一套
Android → Kotlin / Java + XML → 团队 A
iOS → Swift / ObjC + Storyboard → 团队 B
问题:
├── 两套代码,维护成本翻倍
├── 功能不同步,容易出现「Android 有但 iOS 没有」
├── 人力资源浪费严重
└── UI 和交互难以统一React Native 的方案
React Native 方案:一套代码,双端原生
React + TypeScript
│
React Native
╱ ╲
Android iOS
(原生视图) (原生视图)
优势:
├── 一套代码 → Android + iOS 原生应用
├── 学 React 就能写移动端 → Web 前端无缝转型
├── 原生渲染 → 性能接近纯原生 App
├── 热更新 → 不发版也能修 Bug
└── 社区生态丰富(120k+ Star,海量第三方库)React Native vs 其他方案
| 方案 | 渲染方式 | 性能 | 开发语言 | 适合场景 |
|---|---|---|---|---|
| React Native | 原生组件 | ⭐⭐⭐⭐ | React + TS | 已有 React 技术栈 |
| Flutter | 自绘引擎 | ⭐⭐⭐⭐⭐ | Dart | 追求极致 UI 一致性 |
| Uni-app | WebView / 原生 | ⭐⭐⭐ | Vue | 多端小程序 + App |
| 原生开发 | 原生 | ⭐⭐⭐⭐⭐ | Kotlin/Swift | 重性能、硬件交互 |
🛠 1. 环境搭建
前置要求
bash
# 确认 Node.js 版本(需要 >= 18)
node -v # v20.x.x
# 确认 npm 版本
npm -v # 10.x.x
# 安装 Watchman(macOS 推荐,用于文件监听)
brew install watchman方式一:Expo(推荐新手)
Expo 是 React Native 官方推荐的框架,开箱即用,无需配置原生环境:
bash
# 创建 Expo 项目
npx create-expo-app@latest my-rn-app
cd my-rn-app
# 启动开发服务器
npx expo start然后用手机安装 Expo Go App,扫描终端中的二维码即可预览。
Tips:Expo 现在已经是 React Native 官方推荐的入门方式,绝大多数场景都适用!
方式二:React Native CLI(需要原生环境)
如果需要接入原生模块或已有原生项目,可以使用 CLI 方式:
macOS + iOS 环境
bash
# 1. 安装 Xcode(App Store 下载)
# 确保 Xcode Command Line Tools 已安装
xcode-select --install
# 2. 安装 CocoaPods(iOS 依赖管理)
sudo gem install cocoapods
# 3. 创建项目
npx @react-native-community/cli init MyRNApp
# 4. 运行 iOS
cd MyRNApp
npx react-native run-iosmacOS + Android 环境
bash
# 1. 安装 Android Studio
# 下载地址:https://developer.android.com/studio
# 2. 配置 Android SDK
# Android Studio → Settings → SDK Manager
# 安装 Android 14 (API 34) SDK
# 3. 配置环境变量(~/.zshrc)
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/platform-tools
# 4. 运行 Android
npx react-native run-android推荐开发工具
| 工具 | 用途 |
|---|---|
| VS Code | 代码编辑器(装 React Native Tools 插件) |
| Expo Go | 手机端预览 App(扫码即用) |
| Android Studio | Android 模拟器 + 调试 |
| Xcode | iOS 模拟器 + 调试(仅 macOS) |
| Flipper / React DevTools | 调试工具 |
📁 2. 项目结构解析(Expo 项目)
my-rn-app/
├── app/ # 📂 页面目录(基于文件的路由)
│ ├── _layout.tsx # 根布局
│ ├── (tabs)/ # Tab 导航组
│ │ ├── _layout.tsx # Tab 布局
│ │ ├── index.tsx # 首页 Tab
│ │ └── explore.tsx # 发现 Tab
│ └── +not-found.tsx # 404 页面
├── assets/ # 📂 静态资源(图片、字体)
│ ├── images/
│ └── fonts/
├── components/ # 📂 公共组件
├── constants/ # 📂 常量定义
│ └── Colors.ts # 颜色主题
├── hooks/ # 📂 自定义 Hook
├── app.json # 📄 Expo 配置
├── tsconfig.json # 📄 TypeScript 配置
├── package.json # 📄 依赖管理
└── babel.config.js # 📄 Babel 配置关键文件解读
typescript
// app.json — Expo 配置
{
"expo": {
"name": "my-rn-app",
"slug": "my-rn-app",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"splash": {
"image": "./assets/images/splash-icon.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"supportsTablet": true,
"bundleIdentifier": "com.example.myrnapp"
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"package": "com.example.myrnapp"
}
}
}typescript
// app/_layout.tsx — 根布局
import { Stack } from 'expo-router';
export default function RootLayout() {
return (
<Stack>
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
<Stack.Screen name="+not-found" />
</Stack>
);
}🚀 3. 运行项目
Expo 项目启动
bash
# 启动开发服务器
npx expo start
# 显示二维码和菜单:
# › Press s │ switch to Expo Go
# › Press a │ open Android
# › Press i │ open iOS simulator
# › Press w │ open web
# › Press r │ reload app
# › Press j │ open debugger
# 快捷启动命令
npx expo start --ios # 直接启动 iOS 模拟器
npx expo start --android # 直接启动 Android 模拟器
npx expo start --web # 启动 Web 版本真机调试
📱 iOS 真机:
1. 手机安装 Expo Go App
2. 确保手机和电脑在同一 WiFi
3. 打开 Expo Go,扫描终端二维码
📱 Android 真机:
1. 手机安装 Expo Go App
2. 确保手机和电脑在同一 WiFi
3. 打开 Expo Go,扫描终端二维码📝 4. 第一个页面
typescript
// app/(tabs)/index.tsx
import { StyleSheet, View, Text, Pressable, Image, Alert } from 'react-native';
import { useState, useCallback } from 'react';
export default function HomeScreen() {
const [count, setCount] = useState(0);
const handlePress = useCallback(() => {
setCount(prev => prev + 1);
Alert.alert('🎉', '点击了!');
}, []);
return (
<View style={styles.container}>
<Image
source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }}
style={styles.logo}
/>
<Text style={styles.title}>欢迎使用 React Native</Text>
<Text style={styles.subtitle}>用 React 写原生应用 🚀</Text>
<View style={styles.counter}>
<Text style={styles.count}>{count}</Text>
<Pressable style={styles.btn} onPress={handlePress}>
<Text style={styles.btnText}>点我 +1</Text>
</Pressable>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
padding: 24,
backgroundColor: '#fff',
},
logo: {
width: 80,
height: 80,
marginBottom: 24,
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#1a1a1a',
marginBottom: 8,
},
subtitle: {
fontSize: 16,
color: '#666',
marginBottom: 48,
},
counter: {
alignItems: 'center',
},
count: {
fontSize: 64,
fontWeight: 'bold',
color: '#6366F1',
},
btn: {
marginTop: 16,
backgroundColor: '#6366F1',
paddingHorizontal: 32,
paddingVertical: 12,
borderRadius: 12,
},
btnText: {
color: '#fff',
fontSize: 16,
fontWeight: '600',
},
});⚠️ 注意:React Native 使用
StyleSheet.create()来定义样式,属性名是驼峰命名 (如backgroundColor而不是background-color),单位不写px,默认是逻辑像素。
🔍 5. React Native 与 React Web 对比
| 概念 | React Web | React Native |
|---|---|---|
| 基础容器 | <div> | <View> |
| 文本显示 | <span> / <p> | <Text>(文本必须放在 Text 内) |
| 图片 | <img src=""> | <Image source=> |
| 输入框 | <input> | <TextInput> |
| 按钮 | <button> | <Pressable> / <TouchableOpacity> |
| 滚动容器 | 自动滚动 | <ScrollView> / <FlatList> |
| CSS 类名 | className="box" | style={styles.box} |
| 样式写法 | CSS / Sass | StyleSheet.create({}) |
| 布局 | 多种布局 | 默认 Flexbox(且默认纵向) |
| 点击事件 | onClick | onPress |
| 路由 | react-router | expo-router / react-navigation |
tsx
// React Web 写法:
<div className="card" onClick={handleClick}>
<img src="logo.png" />
<span>Hello World</span>
</div>
// React Native 写法:
<View style={styles.card}>
<Pressable onPress={handlePress}>
<Image source={require('./logo.png')} />
<Text>Hello World</Text>
</Pressable>
</View>✅ 本篇小结 Checklist
下一篇预告:《核心组件与样式》—— 学习 React Native 的内置组件体系和 Flexbox 布局。
本文是「RN 从零到一」系列第 1 篇,共 10 篇。
📝 作者:NIHoa | 系列:RN从零到一系列 | 更新日期:2025-04-01