从抵触到真香:我用 React Native 写了人生第一个 App
说实话,我以前是坚决反对用“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 默认有 elevation 和 z-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-native 和 react-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