React Native快速入门:构建你的第一个APP
大家好,我是小林,985某高校计算机专业大三狗(现在应该叫“准毕业生”了),目前在一家中型互联网公司实习两个月。每天早上8点雷打不动坐在工位上开始搬砖——别问为什么这么早,问就是怕产品经理突然冲过来塞需求。
上周五晚上10点,我还在为一个诡异的动画卡顿问题抓狂,突然收到mentor的消息:“下周要跟区块链团队联调一个移动端demo,你先搭个React Native基础壳子吧。”
我当时心里一万只羊驼奔腾而过:我前端都还没玩明白呢,现在又要搞跨端?还跟区块链扯上关系?
但转念一想,秋招快到了,简历上要是能写“主导RN项目+区块链集成”,那不得香死HR?于是咬咬牙,撸起袖子就开始干。今天这篇技术分享,就是我踩坑三天后总结出来的React Native极速上手指南,纯干货,无废话。
为啥选 React Native?真不是跟风!
说实话,一开始我对RN是有点偏见的。总觉得“JavaScript写原生”听着就不太靠谱,性能肯定不如Flutter或者原生开发。但在我们组的实际场景下,RN成了最优解:
- 团队主力是Web前端,JS栈熟得不能再熟
- 产品要求iOS + Android双端同步上线
- 区块链那边只提供RESTful API和WebSocket,没有SDK
- Deadline只有两周!(对,又是熟悉的节奏)
而且公司内部已经有几个RN项目跑在线上,稳定性还行。运维大哥甚至开玩笑说:“你们前端再搞崩一次,我就把服务器名改成‘林某人专用重启机’。”
所以,与其挣扎,不如拥抱。当需求追着你跑的时候,框架选择往往不是技术最优,而是团队最快。
环境搭建:你以为很简单?天真!
按照官方文档 npx react-native init MyApp 一敲,以为万事大吉?Too young too simple。
我在Mac M1上折腾了整整一个下午,遇到两个经典坑:
- Xcode版本不兼容:RN 0.72 要求 Xcode 14.3+,但我装的是14.2(别问,问就是公司IT统一配的)。
- Android NDK路径没配:Gradle build 直接报错
NDK not configured。
解决方法?翻遍Stack Overflow + 公司内部Wiki,最后靠一条命令救场:
# 强制指定NDK版本(在android/local.properties里加)
ndk.dir=/Users/lin/Library/Android/sdk/ndk/25.1.8937393
建议:直接用最新版React Native CLI + Expo Go调试,省掉90%环境问题。 我们组新人都被强制要求先用Expo跑通Demo,再考虑裸露项目(bare workflow)。
写个最简APP:从“Hello World”到区块链请求
目标很明确:做一个页面,显示当前以太坊主网最新区块号。听起来简单,但涉及网络请求、状态管理、平台适配三大核心。
第一步:创建组件
// App.tsx
import React, { useEffect, useState } from 'react';
import { View, Text, Platform, StyleSheet } from 'react-native';
const App = () => {
const [blockNumber, setBlockNumber] = useState<string | null>(null);
useEffect(() => {
fetchLatestBlock();
}, []);
const fetchLatestBlock = async () => {
try {
// 这里调用的是Infura的以太坊节点(需API Key)
const res = await fetch('https://mainnet.infura.io/v3/YOUR_API_KEY', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: "2.0",
method: "eth_blockNumber",
params: [],
id: 1
})
});
const data = await res.json();
// eth_blockNumber返回的是16进制字符串,转成十进制
const decimalBlock = parseInt(data.result, 16).toString();
setBlockNumber(decimalBlock);
} catch (err) {
console.error('Failed to fetch block number:', err);
setBlockNumber('Error');
}
};
return (
<View style={styles.container}>
<Text style={styles.title}>当前以太坊区块高度</Text>
<Text style={styles.blockNumber}>{blockNumber || 'Loading...'}</Text>
<Text style={styles.platform}>运行平台: {Platform.OS}</Text>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f5f5f5',
},
title: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 20,
},
blockNumber: {
fontSize: 32,
color: '#1e88e5',
fontWeight: '600',
},
platform: {
marginTop: 30,
color: '#666',
}
});
export default App;
📌 注意:
Platform.OS是RN提供的跨平台判断工具,值为'ios'或'android'。以后做平台特有逻辑就靠它了。
第二步:处理权限(Android专属)
在Android 9+ 上,明文HTTP请求默认被禁止!虽然Infura是HTTPS,但如果你本地mock用HTTP,会直接报 Cleartext HTTP traffic not permitted。
解决方案:在 android/app/src/main/AndroidManifest.xml 中添加:
<application
android:usesCleartextTraffic="true"
... >
(当然,线上千万别开!)
动画 & 交互:我的兴趣所在!
既然对前端动画感兴趣,那必须加点料。比如:区块号更新时加个淡入效果?
RN自带的 Animated API 虽然强大,但写起来像在造火箭。推荐用社区库 react-native-reanimated,配合Hooks简直丝滑。
不过考虑到这是入门项目,我用了最简单的 LayoutAnimation(仅限iOS稳定,Android需额外配置):
import { LayoutAnimation, UIManager } from 'react-native';
// Android 需要开启
if (Platform.OS === 'android') {
if (UIManager.setLayoutAnimationEnabledExperimental) {
UIManager.setLayoutAnimationEnabledExperimental(true);
}
}
// 更新数据前触发动画
const updateBlock = (newBlock: string) => {
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
setBlockNumber(newBlock);
};
效果:数字变化时会有轻微缩放+透明度过渡。虽然简单,但用户体验立马提升一个档次。产品经理看了都说“这钱花得值”(其实没花钱,纯代码 😏)。
性能与适配:别等上线才哭
RN最大的痛点之一就是平台差异。同一个样式,在iOS上完美,Android可能文字截断、按钮错位。
我整理了一份避坑清单:
| 问题 | iOS表现 | Android表现 | 解决方案 |
|---|---|---|---|
| 字体默认粗细 | 较细 | 较粗 | 显式设置 fontWeight: '400' |
| 按钮点击区域 | 自动扩大 | 严格按尺寸 | 用 Pressable + hitSlop |
| 状态栏高度 | 固定20px | 可能带刘海/挖孔 | 用 StatusBar.currentHeight |
| 网络超时 | 默认无限制 | 10秒超时 | 手动设置 timeout |
另外,不要滥用 console.log!在真机上会严重拖慢JS线程。我们之前有个同事在渲染列表里打log,结果Android低端机直接卡成PPT,被测试小姐姐追着骂了半小时。
发布到应用市场?先过这几关!
虽然只是Demo,但mentor要求“至少能扫码安装”。于是体验了一把上架流程的酸爽。
iOS(TestFlight)
- 需要Apple Developer账号(公司有)
- 生成证书、Provisioning Profile(运维帮忙搞的)
- 用Xcode Archive → Validate → Upload
- 审核?不存在的,TestFlight内测不用审
Android(内部APK分发)
./gradlew assembleRelease- 签名密钥必须配置(否则安装失败)
- 建议开启Proguard混淆(防反编译)
最坑的是:Android打包后发现区块链请求403!
原因:Infura的API Key绑定了Bundle ID / Package Name。本地调试是 com.myapp,发布版却是 com.mycompany.blockchain.demo,直接被拒。
解决:在Infura后台把正式包名加到白名单。所以,永远不要在客户端硬编码敏感Key!(虽然Demo无所谓,但习惯要养好)
和区块链结合:真的只是发个请求?
很多人以为“区块链App = 调个API”,其实远不止如此。
我们这个Demo虽然简单,但背后涉及:
- Web3.js 或 ethers.js 的集成(RN里要用
node-libs-browserpolyfill) - 钱包连接(MetaMask Mobile 支持 deep link)
- 交易签名(需原生模块或第三方SDK)
不过对于入门来说,先跑通数据流更重要。后续可以逐步接入 @walletconnect/react-native-dapp 实现钱包登录,那才是重头戏。
心得总结:三天从零到上线,值不值?
值!太值了!
- 技术层面:掌握了RN核心概念(组件、状态、平台适配、原生桥接)
- 工程层面:理解了CI/CD、证书管理、性能监控(我们用了Sentry)
- 简历层面:成功蹭上“区块链+移动端”热点,面试官眼睛都亮了
最重要的是,我发现跨端开发没那么可怕。RN虽然有些坑,但社区生态成熟,遇到问题基本都能搜到答案。比起从零学Swift/Kotlin,JS栈开发者迁移成本低得多。
给后来者的建议
- 别死磕文档:先跑通一个完整Demo,再回头查细节
- 善用调试工具:React DevTools + Flipper 是神器
- 关注性能红线:避免在render里创建函数、滥用setState
- 别忽视设计规范:iOS用SF Pro,Android用Roboto,别混用
- 和原生同学搞好关系:以后写原生模块还得求他们
最后吐槽一句:昨天联调时,区块链团队说“你们前端怎么连Web3Provider都不懂”,我回了句“你们后端不也分不清Promise和Callback hell?” —— 结果双方安静了三秒,然后一起笑了。技术没有高低,只有分工不同。
好了,我的第一个React Native App已经跑在手机上了,区块号每15秒刷新一次(以太坊出块时间)。虽然简单,但看到自己写的代码在真机上跑起来,那种成就感,真的比吃火锅还爽。
秋招加油!希望这篇分享能帮你少走弯路。有问题评论区见,我一般早上8点就在线(毕竟,早起的鸟儿有Bug修 😅)。
技术分享不易,如果对你有帮助,欢迎点赞/转发。下期可能讲《React Native + WalletConnect 实战》,看反馈决定~

评论 0