React Native 入门实战:从零搭环境到真机跑通 App

作为一个写了几年 React Web 的开发者,我一直对移动端保持着”听说过但没碰过”的距离。这次下定决心,用一天时间从零跑通一个 React Native Demo——环境搭建、真机调试、页面导航全部走一遍。

这篇文章记录整个过程,包括那些让人抓狂的报错。


环境信息

在开始之前,先把环境摆明白,这样踩坑时更容易对症下药:

项目详情
开发机MacBook,Apple M1 Pro(arm64)
系统macOS Darwin 24.6.0
框架React Native CLI(非 Expo)
Node.jsv22.22.2
Java JDKOpenJDK 17.0.16(Zulu)
Android SDKPlatform 36,Build-tools 36
ADBv1.0.41
调试真机华为 Mate 30(Android)

选择 React Native CLI 而非 Expo,主要是想真正理解底层结构,Expo 封装太多反而不适合入门学习。


一、环境搭建

安装 Node.js 和 JDK

brew install node
brew install --cask zulu@17

JDK 选 Zulu 17,React Native 官方要求 JDK 17,其他版本可能会有兼容问题。

配置 Android SDK 环境变量

安装好 Android Studio 后,在 ~/.zshrc 中添加:

export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/emulator
export PATH=$PATH:$ANDROID_HOME/platform-tools

然后:

source ~/.zshrc
adb version
# Android Debug Bridge version 1.0.41 ✅

创建项目

npx @react-native-community/cli@latest init ReactNativeDemo --skip-install
cd ReactNativeDemo
npm install

--skip-install 是为了先把项目结构生成出来,再手动 npm install,这样依赖安装过程更可控。


二、项目结构设计

App 的功能很简单,两个页面:

  • HomeScreen:显示「Hello React Native」+ 一个跳转按钮
  • DetailScreen:展示 Image、FlatList 等基础组件 + 返回按钮

导航使用 @react-navigation/native-stack

npm install @react-navigation/native @react-navigation/native-stack react-native-screens react-native-safe-area-context

目录结构如下:

ReactNativeDemo/
├── src/
│   └── screens/
│       ├── HomeScreen.tsx
│       ├── DetailScreen.tsx
│       ├── DocsScreen.tsx        # 第二轮新增
│       └── DocDetailScreen.tsx   # 第二轮新增
├── docs/                         # 本地 Markdown 文档
├── App.tsx                       # 导航根配置
└── index.js

App.tsx — 路由入口

export type RootStackParamList = {
  Home: undefined;
  Detail: undefined;
  Docs: undefined;
  DocDetail: { file: string; title: string };
};

const Stack = createNativeStackNavigator<RootStackParamList>();

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="Home"
        screenOptions={{
          headerStyle: { backgroundColor: '#4f46e5' },
          headerTintColor: '#fff',
          headerTitleStyle: { fontWeight: 'bold' },
        }}>
        <Stack.Screen name="Home" component={HomeScreen} options={{ title: '首页' }} />
        <Stack.Screen name="Detail" component={DetailScreen} options={{ title: '基础组件' }} />
        <Stack.Screen name="Docs" component={DocsScreen} options={{ title: '开发文档' }} />
        <Stack.Screen
          name="DocDetail"
          component={DocDetailScreen}
          options={({ route }) => ({ title: route.params.title })}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

TypeScript 的路由类型定义是个好习惯,navigate 时会有参数提示和类型检查,避免拼写错误。


三、连接华为 Mate 30 进行真机调试

用模拟器跑 React Native 其实挺慢的,尤其 M1 Mac 上的 Android 模拟器兼容性一般。能用真机尽量用真机。

开启开发者模式

  1. 设置 → 关于手机,连续点击「版本号」7 次
  2. 回到 设置 → 系统 → 开发人员选项
  3. 开启「USB 调试」

验证连接

adb devices
# List of devices attached
# GUL0219B13007173   device

看到 device 就是连接成功了。如果显示 unauthorized,在手机上点「允许」那个弹窗。

编译并安装到手机

# 终端 1:启动 Metro 打包服务
npm start

# 终端 2:编译 + 安装 APK
npx react-native run-android

首次编译需要 3-5 分钟,Gradle 会下载很多依赖。耐心等。


四、踩坑:Unable to load script

这是最经典的坑。App 安装好之后打开,白屏,报错:

Unable to load script. Make sure you're either running a Metro server
or that your bundle is packaged correctly for release.

原因:真机和 Mac 不在同一个网段,手机无法直接访问 Mac 上运行的 Metro 服务(默认端口 8081)。

解决方案:用 ADB 做端口转发,让手机的 8081 端口流量转发到 Mac 的 8081:

adb reverse tcp:8081 tcp:8081

执行完后重新打开 App,瞬间恢复正常。

注意:每次重新插拔 USB 后,这个转发会失效,需要重新执行一次。


五、第二轮迭代:在 App 里内嵌开发文档

基础功能跑通之后,我加了一个有意思的功能:把开发文档直接放进 App 里

想法来自于:写了一堆 Markdown 文档记录踩坑过程,每次要翻着看还得去电脑上找,不如直接在手机 App 里就能看。

新增了两个页面:

  • DocsScreen:文档列表,展示所有 Markdown 文章标题
  • DocDetailScreen:文档详情,渲染 Markdown 内容

文档内容存放在 docs/ 目录下,包括:

  • 01-metro.md — Metro 打包工具说明
  • 02-device-debug.md — 真机调试流程
  • 03-logcat.md — Android 日志查看
  • 04-navigation.md — 页面导航用法

这轮迭代完成后,同样打包成 APK 安装到华为 Mate 30,所有页面运行正常。


六、下次开发的启动步骤

每次重新开发时需要这几步,记在这里备忘:

# 1. 确认设备连接
adb devices

# 2. 设置端口转发(每次接 USB 后都要做)
adb reverse tcp:8081 tcp:8081

# 3. 启动 Metro
cd ReactNativeDemo && npm start

# 4. 手机上打开 App,或摇晃手机选 Reload

总结

从零到真机运行,整个过程大概花了一天。几个关键点:

  1. JDK 必须是 17,其他版本会有 Gradle 兼容问题
  2. 环境变量一定要配好ANDROID_HOME 缺了 ADB 就不能用
  3. 真机调试记得端口转发adb reverse tcp:8081 tcp:8081 是高频命令
  4. 华为手机开发者选项在「关于手机」里点版本号激活,位置比较隐蔽

对于有 React Web 背景的开发者来说,React Native 的组件模型和 Hooks 用法几乎一样,上手不难。难的是环境搭建和调试链路——只要这一关过了,后面写业务代码其实很顺。

项目代码在 GitHub:nacheal/react-natvie-demo