React Native 入门指南
React Native 是一个用于构建原生移动应用的框架,允许开发者使用 JavaScript 和 React 进行开发。本指南将从基础到进阶,涵盖环境搭建、项目创建、组件使用、导航、状态管理等核心内容,帮助你快速上手。
React Native 基础
环境搭建
开始之前,需要配置开发环境。首先安装 Node.js 和 npm,然后全局安装 React Native CLI。对于 Android 开发,需安装 Android Studio;对于 iOS 开发,在 macOS 上需安装 Xcode。最后,配置环境变量以确保工具链正常工作。
# 安装 Node.js 和 npm
# 安装 React Native CLI
npm install -g react-native-cli
# 安装 Android Studio (Android 开发)
# 安装 Xcode (iOS 开发,仅 macOS)
# 配置环境变量
export ANDROID_HOME=$HOME/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
项目创建
创建新项目使用 npx react-native init MyApp 命令,生成一个基本的 React Native 应用结构。进入项目目录后,可以运行应用在 iOS 或 Android 模拟器上。
# 创建新项目
npx react-native init MyApp
# 运行项目
cd MyApp
# iOS
npx react-native run-ios
# Android
npx react-native run-android
基础组件
React Native 提供了一系列内置组件,用于构建用户界面。常用组件包括 View、Text、Image、TextInput、TouchableOpacity、ScrollView 和 FlatList。以下示例展示了这些组件的使用方法。
import React from 'react';
import {
View,
Text,
Image,
TextInput,
TouchableOpacity,
ScrollView,
FlatList,
} from 'react-native';
const BasicComponents = () => {
return (
<View style={styles.container}>
<Text style={styles.text}>Hello React Native</Text>
<Image
source={require('./images/logo.png')}
style={styles.image}
/>
<TextInput
style={styles.input}
placeholder="请输入..."
onChangeText={text => console.log(text)}
/>
<TouchableOpacity
style={styles.button}
onPress={() => console.log('pressed')}
>
<Text>点击我</Text>
</TouchableOpacity>
<FlatList
data={[{id: 1, title: 'Item 1'}, {id: 2, title: 'Item 2'}]}
renderItem={({item}) => <Text>{item.title}</Text>}
keyExtractor={item => item.id.toString()}
/>
</View>
);
};
样式和布局
样式通过 StyleSheet.create 定义,使用 Flexbox 进行布局。React Native 支持常见的样式属性,如颜色、边距、边框等,允许创建响应式设计。
import { StyleSheet } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
text: {
fontSize: 16,
color: '#333',
marginBottom: 10,
},
flexContainer: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
absolutePosition: {
position: 'absolute',
top: 0,
right: 0,
width: 50,
height: 50,
},
card: {
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 8,
padding: 15,
margin: 10,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
});
导航
页面导航通常使用 React Navigation 库。它提供了栈导航器、标签导航器等,方便管理应用的路由和屏幕切换。
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: '首页' }}
/>
<Stack.Screen
name="Details"
component={DetailsScreen}
options={{ title: '详情' }}
/>
</Stack.Navigator>
</NavigationContainer>
);
};
const HomeScreen = ({ navigation }) => {
return (
<View>
<Button
title="跳转到详情"
onPress={() => navigation.navigate('Details', { id: 1 })}
/>
</View>
);
};
const DetailsScreen = ({ route }) => {
const { id } = route.params;
return (
<View>
<Text>Details Screen {id}</Text>
</View>
);
};
状态管理
对于复杂应用,可以使用 Redux 进行状态管理。通过创建 store 和 slice,统一管理应用状态,并在组件中使用 useSelector 和 useDispatch 进行访问和更新。
// store/index.js
import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './counterSlice';
export const store = configureStore({
reducer: {
counter: counterReducer,
},
});
// store/counterSlice.js
import { createSlice } from '@reduxjs/toolkit';
const counterSlice = createSlice({
name: 'counter',
initialState: {
value: 0,
},
reducers: {
increment: state => {
state.value += 1;
},
decrement: state => {
state.value -= 1;
},
},
});
// 组件中使用
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement } from './counterSlice';
const Counter = () => {
const count = useSelector(state => state.counter.value);
const dispatch = useDispatch();
return (
<View>
<Text>Count: {count}</Text>
<Button title="+" onPress={() => dispatch(increment())} />
<Button title="-" onPress={() => dispatch(decrement())} />
</View>
);
};
网络请求
网络请求可以使用 Fetch API 或 Axios 库。Fetch 是内置的,而 Axios 提供了更丰富的功能,如拦截器和默认配置。
// 使用 Fetch
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const json = await response.json();
return json;
} catch (error) {
console.error(error);
}
};
// 使用 Axios
import axios from 'axios';
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
});
const getData = async () => {
try {
const response = await api.get('/data');
return response.data;
} catch (error) {
console.error(error);
}
};
React Native 进阶
自定义组件
创建可复用的自定义组件有助于提高代码维护性。例如,一个自定义按钮组件可以封装样式和交互逻辑。
// components/CustomButton.js
import React from 'react';
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
const CustomButton = ({ title, onPress, style }) => {
return (
<TouchableOpacity
style={[styles.button, style]}
onPress={onPress}
>
<Text style={styles.text}>{title}</Text>
</TouchableOpacity>
);
};
const styles = StyleSheet.create({
button: {
backgroundColor: '#007AFF',
padding: 10,
borderRadius: 5,
alignItems: 'center',
},
text: {
color: '#fff',
fontSize: 16,
},
});
export default CustomButton;
原生模块
当需要访问原生功能时,可以创建原生模块。在 Android 和 iOS 上分别实现,然后在 JavaScript 中调用。
// Android (Java)
public class CustomModule extends ReactContextBaseJavaModule {
@ReactMethod
public void showToast(String message) {
Toast.makeText(getReactApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
}
// iOS (Objective-C)
@implementation CustomModule
RCT_EXPORT_METHOD(showToast:(NSString *)message)
{
// 实现 iOS 原生功能
}
@end
// JavaScript
import { NativeModules } from 'react-native';
const { CustomModule } = NativeModules;
CustomModule.showToast('Hello from native code!');
性能优化
优化性能可以提升应用流畅度。使用 React.memo 避免不必要的重渲染,useCallback 缓存函数,以及 FlatList 的优化属性处理长列表。
// 使用 memo 避免不必要的重渲染
import React, { memo } from 'react';
const ExpensiveComponent = memo(({ data }) => {
return (
// 渲染逻辑
);
});
// 使用 useCallback 缓存函数
import { useCallback } from 'react';
const MyComponent = () => {
const handlePress = useCallback(() => {
// 处理逻辑
}, []);
return <Button onPress={handlePress} />;
};
// 使用 FlatList 优化长列表
<FlatList
data={items}
renderItem={renderItem}
keyExtractor={item => item.id}
initialNumToRender={10}
maxToRenderPerBatch={10}
windowSize={5}
removeClippedSubviews={true}
/>
打包发布
应用开发完成后,需要打包发布。Android 使用 Gradle 生成发布包,iOS 使用 Xcode 进行打包和提交到 App Store。
# Android 打包
cd android
./gradlew assembleRelease
# 生成签名密钥
keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
# iOS 打包
# 使用 Xcode 进行打包和发布
最佳实践建议
- 项目结构组织:保持清晰的目录结构,例如按功能划分 components、screens、navigation、store、api、utils 和 assets 文件夹。
- 代码规范:使用 ESLint 和 Prettier 统一代码风格,组件命名采用大驼峰,文件名与组件名一致,优先使用函数组件和 Hooks。
- 性能优化:使用生产构建、懒加载、优化图片资源、避免内联样式,并选择适当的列表组件。
- 调试技巧:利用 React Native Debugger、console.log、Performance Monitor 和 Chrome 开发者工具进行调试。
常见问题解决
- 启动问题:清理缓存可以解决许多启动异常,使用
npm start -- --reset-cache,并在 Android 和 iOS 目录中运行清理命令。 - 版本兼容:确保 package.json 中的依赖版本兼容,例如 react-native 与导航库的版本匹配。
- 性能问题:检查不必要的重渲染、优化图片和动画、使用 FlatList 或 SectionList 处理列表,避免过度渲染。