选择合适的开发工具
刚开始接触React Native,最纠结的就是选Expo Go还是React Native CLI。我整理了一张对比表,帮你10秒做决定:

工具 | 优点 | 缺点 | 适合场景 |
---|---|---|---|
Expo Go | 无需配置Xcode/Android Studio,手机扫码直接预览 | 复杂原生功能需“ ejected ”(脱离Expo环境) | 快速原型、小项目、Demo开发 |
React Native CLI | 完全控制原生代码,支持定制化功能 | 需要手动配置iOS/Android开发环境 | 大型项目、需调用自定义原生模块 |
如果你是第一次玩React Native,直接选Expo Go——省掉至少2小时的环境配置时间,先体验“写一行代码,手机立刻看到效果”的快乐。
环境配置与项目初始化
1. 安装基础依赖
首先得装Node.js(选最新LTS版本,比如v20.x),官网下载安装后,打开终端验证:
node -v # 输出v20.x.x说明成功
npm -v # 输出对应的npm版本
然后安装Expo CLI(快速开发用这个):
npm install -g expo-cli
2. 初始化项目
终端执行以下命令,创建你的第一个RN项目:
expo init MyFirstRNApp # 项目名随便起,比如“我的RN小应用”
cd MyFirstRNApp # 进入项目目录
expo start # 启动开发服务器
此时终端会弹出一个二维码,打开手机上的Expo Go App(App Store/应用商店搜“Expo Go”下载),扫描二维码——10秒后,手机上就能看到你的App了!
核心组件开发:从Hello World到实用页面
React Native的组件和React几乎一样,但要注意适配手机端的特性(比如触摸事件、屏幕适配)。我们直接写一个登录页面,覆盖最常用的组件:
import React, { useState } from 'react';
import { View, Text, TextInput, Button, StyleSheet, Alert } from 'react-native';
// 登录页面组件
const LoginScreen = () => {
// 用useState管理输入框状态
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
// 登录按钮点击事件
const handleLogin = () => {
if (!email || !password) {
Alert.alert('提示', '请填写邮箱和密码');
return;
}
// 这里可以对接后端接口,比如调用axios发请求
console.log('登录信息:', email, password);
Alert.alert('成功', '登录请求已发送!');
};
return (
<View style={styles.container}>
{/* 标题 */}
<Text style={styles.title}>欢迎登录我的App</Text>
{/* 邮箱输入框 */}
<TextInput
style={styles.input}
placeholder="请输入邮箱"
value={email}
onChangeText={setEmail} // 输入时更新状态
keyboardType="email-address" // 弹出邮箱键盘
autoCapitalize="none" // 不自动大写
/>
{/* 密码输入框 */}
<TextInput
style={styles.input}
placeholder="请输入密码"
value={password}
onChangeText={setPassword}
secureTextEntry // 密码隐藏
/>
{/* 登录按钮 */}
<Button title="立即登录" onPress={handleLogin} />
</View>
);
};
// 样式表(类似CSS,但用React Native的StyleSheet)
const styles = StyleSheet.create({
container: {
flex: 1, // 占满整个屏幕
justifyContent: 'center', // 垂直居中
padding: 20, // 左右内边距
backgroundColor: '#f5f5f5',
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 30,
textAlign: 'center',
},
input: {
height: 50,
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 8,
paddingLeft: 15,
marginBottom: 20,
backgroundColor: '#fff',
},
});
export default LoginScreen;
把这个组件替换App.js
里的内容,手机上立刻就能看到一个能交互的登录页——输入邮箱密码,点按钮会弹提示框,是不是很有成就感?
状态管理:解决组件间数据传递问题
当你的App变复杂(比如有“主题切换”“用户信息共享”),就需要状态管理了。我们用React自带的useContext
做一个主题切换功能,比Redux简单10倍:
1. 创建主题上下文
新建src/context/ThemeContext.js
:
import React, { createContext, useState, useContext } from 'react';
// 创建主题上下文
const ThemeContext = createContext();
// 主题提供者组件(包裹需要共享主题的组件)
export const ThemeProvider = ({ children }) => {
const [isDarkMode, setIsDarkMode] = useState(false); // 默认浅色主题
// 切换主题的方法
const toggleTheme = () => {
setIsDarkMode(prev => !prev);
};
return (
<ThemeContext.Provider value={{ isDarkMode, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
};
// 自定义Hook,方便组件使用主题
export const useTheme = () => useContext(ThemeContext);
2. 在组件中使用主题
修改LoginScreen
,让它根据主题切换颜色:
import { useTheme } from './context/ThemeContext'; // 导入自定义Hook
const LoginScreen = () => {
const { isDarkMode } = useTheme(); // 获取当前主题状态
return (
<View style={[
styles.container,
{ backgroundColor: isDarkMode ? '#1a1a1a' : '#f5f5f5' } // 主题色切换
]}>
<Text style={[
styles.title,
{ color: isDarkMode ? '#fff' : '#000' } // 文字颜色切换
]}>欢迎登录我的App</Text>
{/* 其他组件同理... */}
</View>
);
};
3. 添加主题切换按钮
在App.js里包裹ThemeProvider
,并加一个切换按钮:
import { ThemeProvider, useTheme } from './src/context/ThemeContext';
import LoginScreen from './src/screens/LoginScreen';
const App = () => {
const { toggleTheme } = useTheme(); // 获取切换方法
return (
<ThemeProvider>
<LoginScreen />
{/* 主题切换按钮,放在屏幕右下角 */}
<Button
title="切换主题"
onPress={toggleTheme}
style={{ position: 'absolute', bottom: 20, right: 20 }}
/>
</ThemeProvider>
);
};
export default App;
现在,点“切换主题”按钮,整个App的颜色会立刻变成深色——是不是很神奇?
原生功能集成:调用手机相机
React Native能直接调用手机的原生功能(比如相机、定位、相册),用Expo的话更简单——直接装现成的库:
1. 安装相机库
终端执行:
expo install expo-camera
2. 写一个相机组件
新建src/screens/CameraScreen.js
:
import React, { useState, useEffect, useRef } from 'react';
import { View, Button, Alert } from 'react-native';
import { Camera } from 'expo-camera';
import { useTheme } from '../context/ThemeContext';
const CameraScreen = () => {
const { isDarkMode } = useTheme();
const [hasPermission, setHasPermission] = useState(null);
const cameraRef = useRef(null); // 相机引用,用来拍照
// 请求相机权限
useEffect(() => {
(async () => {
const { status } = await Camera.requestCameraPermissionsAsync();
setHasPermission(status === 'granted');
})();
}, []);
// 没有权限时显示提示
if (hasPermission === false) {
return <Text style={{ color: isDarkMode ? '#fff' : '#000' }}>需要相机权限才能使用</Text>;
}
// 拍照函数
const takePicture = async () => {
if (cameraRef.current) {
const photo = await cameraRef.current.takePictureAsync();
Alert.alert('成功', `照片保存路径:${photo.uri}`);
}
};
return (
<View style={{ flex: 1 }}>
<Camera
ref={cameraRef}
style={{ flex: 1 }}
type={Camera.Constants.Type.back} // 后置摄像头
/>
<Button
title="拍一张"
onPress={takePicture}
style={{ position: 'absolute', bottom: 20, alignSelf: 'center' }}
/>
</View>
);
};
export default CameraScreen;
现在,你的App已经能调用手机相机拍照了——这就是跨平台的威力:一份代码,iOS和Android都能用!
打包上线:把App发到应用商店
当你的App开发完成,就可以打包成安装包,发到App Store或应用商店了。Expo提供了一键打包功能,超方便:
1. 配置app.json
打开项目根目录的app.json
,填写你的App信息(比如名称、图标、包名):
{
"expo": {
"name": "我的第一个RN App", // App名称
"slug": "my-first-rn-app", // 项目唯一标识(小写,无空格)
"version": "1.0.0", // 版本号
"icon": "./assets/icon.png", // App图标(放在assets文件夹里)
"splash": { // 启动页
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"bundleIdentifier": "com.yourname.myfirstrnapp", // iOS包名(类似“com.张三.我的App”)
"buildNumber": "1.0.0"
},
"android": {
"package": "com.yourname.myfirstrnapp", // Android包名(和iOS类似)
"versionCode": 1
}
}
}
2. 打包iOS安装包
终端执行:
expo build:ios
按照提示登录你的Apple Developer账号(需要付费,每年688元),等待30分钟左右,Expo会给你一个IPA文件——把这个文件上传到App Store Connect,等待苹果审核通过,就能在App Store搜到你的App了!
3. 打包Android安装包
终端执行:
expo build:android
同样需要登录Google Play Console账号(一次性付费25美元),打包完成后得到APK文件,上传到Google Play商店,就能让Android用户下载了。
常见坑点与解决方案
我整理了新手最常踩的3个坑,帮你省掉半天调试时间:
- 图片不显示:
- 错误写法:
<Image source={{ uri: './assets/logo.png' }} />
-
正确写法:
<Image source={require('./assets/logo.png')} />
(必须用require
,RN会自动打包图片) -
键盘挡住输入框:
-
安装
expo-keyboard-aware-scroll-view
库,用KeyboardAwareScrollView
包裹页面:expo install expo-keyboard-aware-scroll-view
import { KeyboardAwareScrollView } from 'expo-keyboard-aware-scroll-view'; const LoginScreen = () => { return ( <KeyboardAwareScrollView style={styles.container}> {/* 输入框组件... */} </KeyboardAwareScrollView> ); };
-
列表滑动卡顿:
- 不用
ScrollView
,用FlatList
(RN专门为长列表做了性能优化):import { FlatList, Text } from 'react-native'; const DataList = () => { const data = [{ id: '1', title: ' item1' }, { id: '2', title: 'item2' }]; return ( <FlatList data={data} renderItem={({ item }) => <Text>{item.title}</Text>} keyExtractor={item => item.id} // 必须给每个item一个唯一ID /> ); };
最后:你的第一个RN App已经在路上了!
看到这里,你已经掌握了React Native开发的全流程:从环境配置到打包上线,从组件开发到状态管理,甚至能调用原生相机。接下来,你可以试试加一些功能:比如“获取定位”(用expo-location
库)、“分享到朋友圈”(用expo-sharing
库),或者“接入后端接口”(用axios
发请求)。
你在开发中遇到过什么坑?欢迎在评论区留言,我会一一帮你解答~
原创文章,作者:,如若转载,请注明出处:https://zube.cn/archives/260