官方文档:https://reactnative.dev/docs/getting-started
中文文档:https://rn.nodejs.cn/docs/getting-started
个人中心:https://expo.dev/accounts/leeken
expo:https://expo.dev/go
模拟器https://expo.dev/orbit
expo是一个框架,可以不用模拟器方便开发React Native
手机去应用商店搜索expo go,并安装
npx create-expo-app@latest 创建一个expo项目
npx create-expo-app@latest ./ 在当前目录创建一个expo项目
回答问题:
确定继续吗? y
应用程序名字?
npm install 安装依赖
登录
npx expo login
开发命令
npx expo-doctor 检查环境是否配置正确
npx expo start 运行app
npm run android 运行到andorid 需要模拟器或真机
npm run ios 需要mac安装模拟器或真机
npm run web 运行到web
npm run reset-project 执行脚本,拒绝于package.js中如何定义
npx expo install 包名 包名 手动安装功能组件包
npx expo install 安装所有功能组件包,推荐
一般模拟器访问本机的IP地址为:
exp://10.0.2.2:8081
expo常识
app目录存放视图tsx文件,每个视图文件夹都需要一个_layout.tsx文件,用来实现路由,导航结构,访问控制等
推荐组织架构
duola/
├─ app/ # 路由驱动的页面(Screen)——全部 *.tsx
│ ├─ _layout.tsx # 顶层布局,放导航容器 / 全局 Provider
│ ├─ +not-found.tsx # 404页
│ ├── (tabs)/ # Tab 底部导航页
│ │ ├── index.tsx # (首页)复习页面
│ │ ├── cards.tsx # 卡片库页面
│ │ ├── chat.tsx # 聊天页
│ │ └── settings.tsx # 设置页面
│ ├─ user/ # 用户相关页面,登陆,注册,个人中心
│ └─ test/ # 调试测试模块,正式发布时不引用
│ ├─ sqliteViewer.tsx # sqlite浏览器
│ └─ ...其它测试项.tsx
│
├─ src/ # 业务逻辑层(纯 TypeScript)
│ ├─ user/ # 用户模块逻辑
│ ├─ store/ # 全局状态(读写token等,读设置)
│ ├─ services/ # 与后端、第三方交互
│ ├─ utils/ # 公共工具函数
│ ├─ database/ # expo-sqlite方法
│ ├─ test/ # 测试模块逻辑部分,正式发布时不引用
│ └─ theme/ # 主题 / 样式变量,UI 库定制
│
├─ assets/
│ ├─ images/ # 静态图片
│ ├─ fonts/ # 自定义字体
│ └─ icons/ # SVG/PNG 图标
│
├─ hooks/ # 跨模块共用的自定义 Hook(可选)
├─ env.ts # 对 dotenv 或 expo-constants 的封装
└─ package.json
常用功能组件
expo-camera 使用摄像头(拍照/录像) ✅ 是
expo-image-picker 从图库选择图片或拍照上传 ✅ 是
expo-location 获取用户位置、地理定位 ✅ 是
expo-permissions(已废弃) 用于请求权限(新版用 expo-modules-core) ✅ 是
expo-constants 获取常量信息,如应用版本、设备 ID 等 ❌ 否
expo-device 获取设备信息,如品牌、系统版本、类型 ❌ 否
expo-network 网络状态检测(在线/离线) ❌ 否
expo-sensors 加速度计、陀螺仪、磁力计、气压计等传感器数据 ❌ 否
expo-secure-store 安全地存储小量敏感数据,如 token、密码等 ❌ 否
expo-notifications 推送通知(本地和远程) ✅ 是
expo-sharing 调用系统分享功能 ✅ 是
expo-splash-screen 自定义启动页 ❌ 否
expo-status-bar 控制状态栏样式(颜色、显示隐藏等) ❌ 否
expo-linear-gradient 实现渐变背景 ❌ 否
expo-haptics 设备震动反馈(触感) ❌ 否
expo-auth-session 第三方 OAuth 登录(如 Google、Facebook) ✅ 是
expo-clipboard 复制粘贴功能 ❌ 否
expo-image 高性能图片组件(新版 Image) ❌ 否
expo-updates OTA 热更新(Expo Go 和裸包都可用) ❌ 否
expo-font 加载自定义字体 ❌ 否
辅助包
npm install wa-sqlite web中的sqlite
npm install date-fns 轻量日期处理库
npx expo install expo-sqlite expo下的sqlite组件
UI库
模板:https://github.com/obytes/react-native-template-obytes
UI库:https://callstack.github.io/react-native-paper/
tailwind:https://www.nativewind.dev/docs/getting-started/installation
推荐,可以使用tailwindcss写样式
npx rn-new@latest --nativewind
编译和构建
需要翻墙,不然会因为网络原因退出
EAS Build云构建
首先注册expo账号
npm install -g eas-cli
eas login登录
eas build:configure 初始化构建和配置,回答问题:y,然后选择平台
eas build -p android --profile preview 开始云端打包
回答问题,确定包名,然后等待上传构建即可
EAS 本地构建
mac或linux环境下才支持
安装必要的依赖:
Node.js/npm
Android SDK 和 NDK(adnroid需要)
fastlane (iOS需要)
CocoaPods (iOS需要)
npm install -g eas-cli 安装eas环境
eas login 第一次需登录
eas build --platform android --local 本地构建
android studio构建
npx expo prebuild --platform android --clean 生成原生android项目
启动 Android Studio打开项目根下的 android/ 文件夹(首次可能需下载依赖)
菜单 Build > Build Bundle(s)/APK(s) 里选择:Build APK(s)
编译好后,左上角的"android"选择Project Files视图,然后找到这个项目的"android">app>build>outputs>apk>outputs/apk/debug/app-debug.apk
android studio减少体积:
- android\gradle.properties文件:
JS_ENGINE=hermesexpo5.2默认,reactNativeArchitectures=arm64-v8a - android\app\build.gradle文件:
defaultConfig {
//其它配置
resConfigs "zh", "en" // 只保留简体中文和英文资源
ndk { // ➜ NDK 配置
debugSymbolLevel 'none' // 精简 native 符号表
}
}
splits {
abi {
enable true // 开启 ABI 拆分
reset()
include 'armeabi-v7a', 'arm64-v8a' // 只生成 32/64 位 ARM
universalApk false // 不生成大而全的 universal-apk
}
}
buildTypes {
// 其它配置
release {
// Caution! In production, you need to generate your own keystore file.
// see https://reactnative.dev/docs/signed-apk-android.
// signingConfig true // 注释掉使用调试签名
shrinkResources true // 移除未用资源
minifyEnabled true // 开启代码混淆&优化
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
crunchPngs false // 禁用 PNG 压缩
}
}
- 生成 release APK:
./gradlew clean assembleRelease
减少安装包体积
npx expo install --fix 分析包体积
npm ls --depth=0 检查未使用依赖
消息闪现
npm i react-native-root-toast
https://www.npmjs.com/package/react-native-root-toast
要在入口ts文件中使用
// app\_layout.tsx:
import { RootSiblingParent } from 'react-native-root-siblings';
return (
<RootSiblingParent>
// 其它app标签
</RootSiblingParent>
);
使用闪现
import Toast from 'react-native-root-toast';
// 闪现默认配置项
const defaultToastOptions = {
duration: Toast.durations.SHORT, // 持续时间
position: -80, // 距离顶部80像素的位置
hideOnPress: true, // 点击隐藏
};
/**
* @description 显示普通消息提示
* @param {string} message - 提示消息
* @param {object} options - 自定义配置选项
*/
export function showToast(message: string,type_msg:string='info') {
return Toast.show(message, type_msg==='err'?{
...defaultToastOptions,
textColor: '#000', //黑色字体
backgroundColor: '#FFA500', //橙色背景
opacity: 1, // 透明度
}:{
...defaultToastOptions,
textColor: '#FFF',
});
}
设备权限开启
app.json:
"expo": {
"ios": {
"infoPlist": {
"NSMicrophoneUsageDescription": "此应用需要访问麦克风进行录音功能"
}
},
"android": {
"permissions": [
"RECORD_AUDIO",
"WRITE_EXTERNAL_STORAGE",
"READ_EXTERNAL_STORAGE"
],
},
}
npx expo install expo-audio
app.json:
{
"expo": {
"plugins": [
[
"expo-audio",
{
"microphonePermission": "Allow $(PRODUCT_NAME) to access your microphone."
}
]
]
}
}
集成tailwindcss
RN版tailwind文档:
https://www.nativewind.dev/docs/getting-started/installation
二选一:
npx rn-new@latest --nativewind 安装一个初始expo+tailwind脚手架
或者已经有expo项目,则使用以下方法安装
npx expo install nativewind react-native-reanimated@~3.17.4 react-native-safe-area-context@5.4.0 必要依赖
npx expo install --dev tailwindcss@^3.4.17 prettier-plugin-tailwindcss@^0.5.11 仅开发时的依赖(区分安装不会打包进app)
准备项:
app.json: "expo": "web": "bundler": 必须是"metro"
npx tailwindcss init 初始化,会创建tailwind.config.js文件
编辑tailwind.config.js:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./app/**/*.{ts,tsx}"], // app目录下的tsx才可能包含界面样式
presets: [require("nativewind/preset")],
theme: {
extend: {},
},
plugins: [],
}
项目根目录创建一个global.css
@tailwind base;
@tailwind components;
@tailwind utilities;
根目录添加babel.config.js:
module.exports = function (api) {
api.cache(true);
return {
presets: [
["babel-preset-expo", { jsxImportSource: "nativewind" }],
"nativewind/babel",
],
};
};
修改metro.config.js:
const { withNativeWind } = require('nativewind/metro'); //添加
//其它配置
module.exports = withNativeWind(config, { input: './global.css' }) //修改
根目录创建创建nativewind-env.d.ts(可选)
/// <reference types="nativewind/types" />
修改tsconfig.json:(官方没说)
` "include": [
// 添加
"nativewind-env.d.ts"
]
如果使用expo的路由在app/_layout.tsx 文件中导入
import '../global.css';
如果不是expo路由则可能是index.js
我遇到不生效的问题,编辑一下组件文字显示生效了
expo 错误疑难杂症
如果异步连接sqlite出现未关闭问题,使用下面这个,每次使用都重新连接:待验证
const db = await SQLite.openDatabaseAsync(databaseFile, {
useNewConnection: true
});