从抵触到真香:我用 React Native 写了人生第一个 App

FastAPI跑起来
2025-12-14 18:49
阅读 276

说实话,我以前是坚决反对用“AI 写代码”的。不是因为我不相信技术进步,而是觉得代码这东西,得自己一行一行敲,才能真正理解逻辑、调试 Bug、感受架构之美。结果去年年底,被逼无奈,不仅用了 AI 辅助写文档,还差点让 Copilot 帮我重构组件——现在?嗯…真香。

我是成都一名普通前端工程师,喜欢在深夜安静地撸代码,效率高、干扰少,偶尔还能点个冒菜配可乐(别笑,这是成都程序员的标配)。我们团队不大,但节奏挺舒服,老板也不搞“996福报”那一套,唯独一点:产品经理总在周五下午五点半甩过来一句“这个需求下周上线,UI 已经给好了”。

上周五就是典型例子。他说:“咱们后台有个数据展示系统,能不能搞个移动端看看?简单点就行。”
我说:“行啊,H5 套壳?”
他说:“不行,要原生体验,上架应用商店那种。”
我内心 OS:你怕不是以为原生 App 是用 Excel 拖拽出来的?

但转念一想,正好趁机学 React Native(RN)——毕竟现在跨端方案卷成麻花了,Flutter、Taro、uni-app 各有拥趸,而 RN 背靠 Meta,社区成熟,说不定哪天跳槽就用上了。于是周末两天没出门,窝在家啃文档、踩坑、debug,终于把第一个 RN App 跑起来了。今天这篇技术分享,就把我从零到上架的实战经验全盘托出,尤其适合像我一样“被迫转型”的前端老油条。


为什么选 React Native?而不是……爬虫?

先澄清一个误会:有人一听“快速开发”,第一反应是“那不如写个 Python 爬虫抓数据,再丢给 WebView”。但兄弟,爬虫是拿数据的,不是做交互的。我们这次的需求是要用户登录、查看实时报表、接收推送通知——这些都得走正规 API,还得有良好 UX。

RN 的优势在于:

  • 用 React 语法写 UI,对我们前端来说几乎零学习成本
  • 一套代码跑 iOS 和 Android(虽然最后还是得调平台差异)
  • 社区轮子多,比如导航、状态管理、网络请求都有成熟方案
  • 热更新能力(虽然后来发现国内安卓市场限制很多)

更重要的是,它真的快。周日晚上十点,我建好项目,凌晨两点就把首页骨架搭完了。那一刻,我仿佛看到了双11期间被 Vue + Cordova 折磨到秃头的自己——泪目。


踩坑实录:从 npx react-native init 到真机跑起来

第一坑:环境配置地狱

RN 最劝退新人的就是环境配置。我 macOS 装了 Xcode,Android Studio 也早有了,但还是卡在 CocoaPods 和 Gradle 版本冲突上。

# 别信网上那些“一键脚本”,建议直接用官方 CLI
npx react-native init MyFirstApp

跑完之后,iOS 部分还好,cd ios && pod install 顺利。但 Android 编译直接报错:

Could not resolve com.android.tools.build:gradle:7.2.1

查了一圈,发现是 Android Studio 升级后默认用 AGP 8.0,而 RN 0.72 还没完全适配。解决方案?手动降级 android/build.gradle 里的 gradle 版本:

dependencies {
    classpath("com.android.tools.build:gradle:7.4.2") // 别用 8.x
}

顺便吐槽:运维同事看到我改 gradle 文件,一脸“你又在搞什么邪术”的表情。


第二坑:平台差异,比女朋友的心还难猜

RN 宣称“Learn Once, Write Anywhere”,但现实是“Write Once, Debug Everywhere”。

比如我用 View 做容器,在 iOS 上 padding 正常,Android 上却挤成一团。后来发现 Android 默认有 elevationz-index 干扰,得显式设 style={{ flex: 1 }} 才行。

还有字体:iOS 默认用 San Francisco,Android 用 Roboto,但中文显示效果天差地别。最后统一引入 react-native-vector-icons + 自定义字体包才解决。

最离谱的是状态栏。iOS 的刘海屏和 Android 的挖孔屏处理逻辑完全不同,光是适配安全区域就让我熬到凌晨三点。推荐用 react-native-safe-area-context,别自己算 StatusBar.currentHeight,那玩意儿在折叠屏上直接崩。


实战:构建一个“极简数据看板” App

我们的目标很明确:用户登录 → 获取 token → 请求接口 → 展示图表。听起来简单,但细节魔鬼。

1. 项目结构(注重可读性!)

我坚持“代码即文档”的原则,所以目录这样分:

src/
├── api/          # 网络请求封装
├── components/   # 可复用组件
├── screens/      # 页面级组件
├── utils/        # 工具函数
├── types/        # TypeScript 类型定义
└── assets/       # 图片、字体等

2. 关键代码:带拦截器的 Axios 封装

虽然 RN 有 fetch,但我习惯用 Axios。重点是加 token 自动刷新错误统一处理

// src/api/client.ts
import axios from 'axios';
import { refreshToken } from './auth';

const client = axios.create({
  baseURL: 'https://api.yourcompany.com',
  timeout: 10000,
});

client.interceptors.request.use(config => {
  const token = getTokenFromStorage(); // 假设你有存储方案
  if (token) config.headers.Authorization = `Bearer ${token}`;
  return config;
});

client.interceptors.response.use(
  response => response,
  async error => {
    if (error.response?.status === 401) {
      try {
        const newToken = await refreshToken();
        // 重试原请求
        return client.request(error.config);
      } catch (refreshError) {
        // 跳转登录页
        navigationRef.navigate('Login');
        return Promise.reject(refreshError);
      }
    }
    return Promise.reject(error);
  }
);

export default client;

💡 自嘲时刻:第一次没加拦截器,测试同学登出后疯狂刷接口,服务器直接报警。运维在群里@我:“你这 App 是 DDOS 工具吗?”

3. 图表渲染:用 react-native-svg-charts

原生不支持 Canvas,所以 ECharts 不能直接用。我试了 victory-nativereact-native-chart-kit,最后选了前者,因为支持 TypeScript 且定制性强。

// src/components/LineChart.tsx
import { LineChart } from 'react-native-svg-charts';
import * as shape from 'd3-shape';

const MyLineChart = ({ data }) => (
  <LineChart
    style={{ height: 200 }}
    data={data}
    svg={{ stroke: 'rgb(134, 65, 244)' }}
    curve={shape.curveNatural}
    contentInset={{ top: 20, bottom: 20 }}
  />
);

性能上要注意:不要在 render 里生成新数组,否则每次 setState 都会重绘整个图表,帧率直接掉到 10fps。


性能优化 & 用户体验:别让用户骂你

启动速度

RN 默认启动有个白屏,特别丑。解决方案:

  • iOS:在 AppDelegate.m 里设置启动图(LaunchScreen.storyboard)
  • Android:自定义 SplashScreen,用 react-native-bootsplash

包体积

初始 APK 有 40MB+,吓死人。优化手段:

  • 启用 Hermes 引擎(RN 默认已集成)
  • 移除未用的 native 模块(比如你没用相机,就别装 react-native-camera
  • 用 Proguard 混淆压缩
优化前 优化后
42 MB 28 MB

真机调试技巧

  • iOS:摇一摇手机唤出开发者菜单
  • Android:adb shell input keyevent 82 模拟菜单键
  • 永远不要在模拟器测性能!我司测试机是千元机,跑起来卡成 PPT,才知道有些动画得关掉

发布上架:你以为写完就结束了?

天真!

  • iOS:需要 Apple Developer 账号(¥688/年),打包用 Xcode Archive,审核通常 1-3 天。注意隐私描述(NSLocationWhenInUseUsageDescription)必须写清楚,否则秒拒。
  • Android:生成签名 APK 或 AAB,上传 Google Play。但国内?得分别上架华为、小米、OPPO 应用市场,每个都要单独注册企业账号,还要过他们的“安全检测”——有一次因为用了 console.log 被判“存在调试信息”,差点没过。

最骚的是,安卓热更新在国内基本废了。各大厂商禁止动态加载 dex,所以别指望 CodePush 救你。所有逻辑变更都得重新发版。


总结:从抗拒到拥抱,我悟了

回看这两周,从“RN 是啥?能吃吗?”到成功上架内部工具 App,最大的收获不是技术本身,而是心态转变。

以前我觉得“原生才是王道”,看不起跨端方案。但现在明白:没有银弹,只有合适场景。对于中小团队、MVP 产品、内部工具,RN 的开发效率碾压原生。当然,如果你要做高性能游戏或复杂动画,那还是老老实实用 Kotlin/Swift 吧。

至于 AI 写代码?我现在会让 Copilot 帮我生成 boilerplate(比如 Redux Toolkit 的 slice 模板),但核心逻辑依然亲手写——毕竟,代码是有灵魂的,而灵魂不能外包

最后,如果你也在成都,欢迎约个茶馆聊技术(或者一起吐槽产品经理)。深夜写代码的日子,总得有点烟火气才完整。

附:我的 RN 学习资源清单

  • 官方文档(英文版比中文更新快)
  • React Native Paper(UI 组件库,设计规范)
  • Expo(如果你想跳过原生配置,但功能受限)
  • GitHub 搜 “react-native-awesome” 看精选库列表

搞定收工,冒菜走起!

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝