React Native 教程
什么是 React Native?
React Native 是 Facebook 开发的一个开源框架,用于使用 JavaScript 和 React 构建真正的原生移动应用。它允许开发者使用相同的代码库为 iOS 和 Android 平台开发应用。
核心特点
- 跨平台开发:一次编写,多平台运行(iOS 和 Android)
- 原生组件:使用真正的原生组件而非 WebView
- 热重载:快速刷新查看代码更改
- 社区支持:庞大的开发者社区和丰富的第三方库
- 性能接近原生:通过桥接技术与原生代码通信
与原生开发对比
特性 | React Native | 原生开发 |
---|---|---|
语言 | JavaScript | Java/Kotlin (Android), Swift/Obj-C (iOS) |
性能 | 接近原生 | 最佳 |
开发速度 | 快 | 慢 |
代码复用 | 高 (跨平台) | 低 |
UI 一致性 | 需要适配 | 原生体验 |
第三方库 | JavaScript 生态 | 原生生态 |
与混合应用对比
React Native 不同于 Cordova/Ionic 等混合应用框架,它:
- 不使用 WebView 渲染
- 生成真正的原生视图
- 性能更好
- 用户体验更接近原生
二、环境搭建
1. 开发环境要求
macOS (iOS 和 Android 开发)
- Node.js 12 LTS 或更高
- Watchman (
brew install watchman
) - Xcode (iOS 开发)
- Android Studio (Android 开发)
- JDK 8 或更高
Windows (仅 Android 开发)
- Node.js 12 LTS 或更高
- Python 2
- JDK 8 或更高
- Android Studio
Linux (仅 Android 开发)
- Node.js 12 LTS 或更高
- Watchman (可选)
- JDK 8 或更高
- Android Studio
2. 安装 React Native CLI
npm install -g react-native-cli
3. 创建新项目
react-native init AwesomeProject
cd AwesomeProject
4. 运行项目
iOS
react-native run-ios
# 或使用 Xcode 打开 ios/AwesomeProject.xcodeproj
Android
react-native run-android
# 确保已启动 Android 模拟器或连接了设备
5. 项目目录结构
AwesomeProject/
android/ - Android 原生代码
ios/ - iOS 原生代码
node_modules/ - 第三方依赖
src/ - 通常用于存放应用代码 (可选)
App.js - 主组件
index.js - 入口文件
package.json - 项目配置
三、基础组件
1. View
相当于 HTML 中的 <div>
,是最基础的容器组件。
jsx
import { View } from 'react-native';
<View style={{ flex: 1, backgroundColor: 'white' }}>
{/* 其他组件 */}
</View>
常用属性:
style
: 应用样式onLayout
: 当组件挂载或布局变化时调用pointerEvents
: 控制视图是否可以成为触摸事件的目标
2. Text
用于显示文本的组件。
jsx
import { Text } from 'react-native';
<Text style={{ fontSize: 24 }}>Hello World!</Text>
常用属性:
style
: 文本样式numberOfLines
: 限制行数onPress
: 点击事件selectable
: 是否可选
3. Image
用于显示图片的组件。
jsx
import { Image } from 'react-native';
// 网络图片
<Image
source={{ uri: 'https://example.com/image.jpg' }}
style={{ width: 200, height: 200 }}
/>
// 本地图片
<Image
source={require('./local-image.png')}
style={{ width: 200, height: 200 }}
/>
常用属性:
source
: 图片源 (URI 或 require)style
: 图片样式resizeMode
: 调整大小模式 ('cover', 'contain', 'stretch' 等)onLoad
: 图片加载完成时调用
4. ScrollView
可滚动的容器组件。
jsx
import { ScrollView, Text } from 'react-native';
<ScrollView>
{Array(20).fill().map((_, i) => (
<Text key={i}>Item {i}</Text>
))}
</ScrollView>
常用属性:
horizontal
: 水平滚动showsHorizontalScrollIndicator
: 显示水平滚动条showsVerticalScrollIndicator
: 显示垂直滚动条refreshControl
: 下拉刷新控件
5. TextInput
文本输入组件。
jsx
import { TextInput } from 'react-native';
<TextInput
placeholder="Enter text"
onChangeText={(text) => console.log(text)}
value={this.state.text}
/>
常用属性:
value
: 输入值placeholder
: 占位文本onChangeText
: 文本变化回调keyboardType
: 键盘类型 ('default', 'numeric', 'email-address' 等)secureTextEntry
: 密码输入
6. Button
基础按钮组件。
jsx
import { Button } from 'react-native';
<Button
title="Press me"
onPress={() => console.log('Pressed')}
/>
常用属性:
title
: 按钮文本onPress
: 点击事件color
: 按钮颜色disabled
: 是否禁用
7. FlatList
高性能列表组件,适合长列表。
jsx
import { FlatList, Text } from 'react-native';
<FlatList
data={[{key: 'a'}, {key: 'b'}]}
renderItem={({item}) => <Text>{item.key}</Text>}
/>
常用属性:
data
: 列表数据renderItem
: 渲染每个项目keyExtractor
: 提取唯一键ListHeaderComponent
: 头部组件ListFooterComponent
: 底部组件onRefresh
: 刷新回调refreshing
: 是否正在刷新
8. SectionList
带分区的列表组件。
jsx
import { SectionList, Text } from 'react-native';
<SectionList
sections={[
{title: 'A', data: ['Apple', 'Avocado']},
{title: 'B', data: ['Banana', 'Blueberry']}
]}
renderItem={({item}) => <Text>{item}</Text>}
renderSectionHeader={({section}) => <Text>{section.title}</Text>}
/>
四、样式与布局
1. StyleSheet
React Native 使用 JavaScript 对象定义样式。
jsx
import { StyleSheet, View, Text } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#fff'
},
title: {
fontSize: 24,
fontWeight: 'bold'
}
});
<View style={styles.container}>
<Text style={styles.title}>Hello</Text>
</View>
样式继承
- 大多数样式属性不会继承 (不同于 CSS)
- 只有 Text 组件内的 Text 组件会继承部分文本样式
2. Flexbox 布局
React Native 使用 Flexbox 进行布局,类似于 CSS Flexbox 但有少许差异。
常用属性:
flex
: 定义组件的伸缩能力flexDirection
: 主轴方向 ('row' 或 'column')justifyContent
: 主轴对齐方式alignItems
: 交叉轴对齐方式alignSelf
: 覆盖父组件的 alignItemsflexWrap
: 是否换行
jsx
<View style={{
flex: 1,
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center'
}}>
<View style={{width: 50, height: 50, backgroundColor: 'red'}} />
<View style={{width: 50, height: 50, backgroundColor: 'green'}} />
<View style={{width: 50, height: 50, backgroundColor: 'blue'}} />
</View>
3. 定位
position
: 'relative'(默认) 或 'absolute'top
,right
,bottom
,left
: 定位偏移量
jsx
<View style={{height: 100}}>
<View style={{
position: 'absolute',
top: 10,
right: 10,
width: 50,
height: 50,
backgroundColor: 'red'
}} />
</View>
4. 平台特定样式
jsx
import { Platform } from 'react-native';
const styles = StyleSheet.create({
container: {
height: Platform.OS === 'ios' ? 200 : 100,
...Platform.select({
ios: {
backgroundColor: 'red'
},
android: {
backgroundColor: 'blue'
}
})
}
});
五、导航
1. React Navigation
最流行的 React Native 导航库。
安装
npm install @react-navigation/native
npm install react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
基本使用
jsx
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
2. 导航类型
堆栈导航 (Stack Navigation)
jsx
// 在屏幕组件中
navigation.navigate('Details', { itemId: 86 });
// 或
navigation.push('Details', { itemId: 86 }); // 允许重复
标签导航 (Tab Navigation)
jsx
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
抽屉导航 (Drawer Navigation)
jsx
import { createDrawerNavigator } from '@react-navigation/drawer';
const Drawer = createDrawerNavigator();
function App() {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Profile" component={ProfileScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
六、状态管理
1. React 状态 (useState)
jsx
import { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<View>
<Text>You clicked {count} times</Text>
<Button title="Click me" onPress={() => setCount(count + 1)} />
</View>
);
}
2. 上下文 API (useContext)
jsx
import React, { createContext, useContext } from 'react';
const ThemeContext = createContext('light');
function App() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar() {
const theme = useContext(ThemeContext);
return <Text>Current theme: {theme}</Text>;
}
3. Redux
安装
npm install redux react-redux
基本使用
jsx
import { createStore } from 'redux';
import { Provider, useSelector, useDispatch } from 'react-redux';
// Reducer
function counter(state = 0, action) {
switch (action.type) {
case 'INCREMENT': return state + 1;
case 'DECREMENT': return state - 1;
default: return state;
}
}
// Store
const store = createStore(counter);
function App() {
return (
<Provider store={store}>
<Counter />
</Provider>
);
}
function Counter() {
const count = useSelector(state => state);
const dispatch = useDispatch();
return (
<View>
<Text>{count}</Text>
<Button title="+" onPress={() => dispatch({ type: 'INCREMENT' })} />
<Button title="-" onPress={() => dispatch({ type: 'DECREMENT' })} />
</View>
);
}
七、网络请求
1. Fetch API
jsx
function App() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/items')
.then(response => response.json())
.then(json => setData(json))
.catch(error => console.error(error));
}, []);
return (
<View>
{data ? <Text>{JSON.stringify(data)}</Text> : <Text>Loading...</Text>}
</View>
);
}
2. Axios
安装
npm install axios
使用
jsx
import axios from 'axios';
function App() {
const [data, setData] = useState(null);
useEffect(() => {
axios.get('https://api.example.com/items')
.then(response => setData(response.data))
.catch(error => console.error(error));
}, []);
// 渲染...
}
八、原生功能集成
1. 访问设备功能
相机
npm install react-native-camera
地理位置
npm install react-native-geolocation-service
通知
npm install react-native-push-notification
2. 原生模块
创建原生模块允许你访问平台特定的 API。
Android 原生模块示例
// MyModule.java
public class MyModule extends ReactContextBaseJavaModule {
MyModule(ReactApplicationContext context) {
super(context);
}
@Override
public String getName() {
return "MyModule";
}
@ReactMethod
public void show(String message, int duration) {
Toast.makeText(getReactApplicationContext(), message, duration).show();
}
}
iOS 原生模块示例
objc
// MyModule.m
#import <React/RCTBridgeModule.h>
@interface RCT_EXTERN_MODULE(MyModule, NSObject)
RCT_EXTERN_METHOD(show:(NSString *)message duration:(double)duration)
@end
JavaScript 中使用
jsx
import { NativeModules } from 'react-native';
NativeModules.MyModule.show('Hello', 5000);
九、调试与测试
1. 调试工具
React Developer Tools
npm install -g react-devtools
react-devtools
Flipper
- 官方推荐的调试工具
- 支持网络请求、日志、数据库等检查
2. 调试技巧
- 摇动设备或按 Cmd+D (iOS) / Cmd+M (Android) 打开开发者菜单
- 使用
console.log
输出日志 - 使用 Chrome 开发者工具调试 JavaScript
3. 测试
Jest 测试
jsx
// sum.js
function sum(a, b) {
return a + b;
}
module.exports = sum;
// sum.test.js
const sum = require('./sum');
test('adds 1 + 2 to equal 3', () => {
expect(sum(1, 2)).toBe(3);
});
组件测试
npm install @testing-library/react-native
jsx
import { render, fireEvent } from '@testing-library/react-native';
import Button from '../Button';
test('button click', () => {
const onPressMock = jest.fn();
const { getByText } = render(<Button title="Press me" onPress={onPressMock} />);
fireEvent.press(getByText('Press me'));
expect(onPressMock).toHaveBeenCalled();
});
十、发布应用
1. Android 发布
生成签名密钥
keytool -genkeypair -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
配置 gradle
编辑 android/app/build.gradle
:
gradle
android {
...
defaultConfig { ... }
signingConfigs {
release {
storeFile file('my-release-key.keystore')
storePassword 'your-password'
keyAlias 'my-key-alias'
keyPassword 'your-password'
}
}
buildTypes {
release {
...
signingConfig signingConfigs.release
}
}
}
生成 APK
cd android && ./gradlew assembleRelease
2. iOS 发布
配置 Xcode
- 打开 Xcode 项目 (
ios/YourProject.xcodeproj
) - 选择目标设备为 "Generic iOS Device"
- 选择 Product > Archive
App Store 发布
- 在 Xcode Organizer 中点击 "Distribute App"
- 选择 "App Store Connect"
- 按照向导完成上传
十一、性能优化
1. 常见性能问题
- 不必要的重新渲染
- 长列表性能问题
- 动画卡顿
- 内存泄漏
2. 优化技巧
使用 PureComponent 或 React.memo
jsx
const MyComponent = React.memo(function MyComponent(props) {
/* 渲染使用 props */
});
优化 FlatList
jsx
<FlatList
data={data}
initialNumToRender={10} // 初始渲染数量
windowSize={5} // 渲染窗口大小
maxToRenderPerBatch={10} // 每批渲染数量
updateCellsBatchingPeriod={50} // 批处理间隔
keyExtractor={(item) => item.id}
renderItem={({item}) => <ListItem item={item} />}
/>
使用 InteractionManager
jsx
InteractionManager.runAfterInteractions(() => {
// 长时间任务
});
使用 Hermes 引擎 (Android)
编辑 android/app/build.gradle
:
gradle
project.ext.react = [
enableHermes: true
]
十二、常见问题与解决方案
1. 常见错误
"Unable to resolve module"
- 确保已安装依赖 (
npm install
) - 尝试重置缓存 (
npm start -- --reset-cache
)
红屏错误
- 仔细阅读错误信息
- 检查组件是否正确导入
- 检查 props 类型是否正确
2. 调试技巧
- 使用
console.log
跟踪执行流程 - 使用断点调试
- 检查网络请求是否正确
3. 社区资源
结语
React Native 是一个强大的框架,可以让你使用 JavaScript 构建真正的原生移动应用。通过本教程,你已经学习了从环境搭建到应用发布的全过程,包括核心组件、样式、导航、状态管理、原生功能集成等关键概念。
要成为 React Native 专家,建议:
- 多实践,构建真实项目
- 阅读官方文档和源码
- 参与社区讨论
- 学习优秀的开源项目
- 关注 React Native 的最新发展
React Native 生态系统在不断进化,保持学习和实践是掌握它的关键。