react-native-app
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseReact Native App Development
React Native 应用开发
Overview
概述
Create professional cross-platform mobile applications using React Native. This skill provides production-ready patterns, best practices, and utilities for building iOS and Android apps with a single codebase.
使用React Native创建专业的跨平台移动应用。本技能提供可用于生产环境的模式、最佳实践和工具,帮助你通过单一代码库构建iOS和Android应用。
Core Project Structure
核心项目结构
Always organize React Native projects with this proven structure:
my-app/
├── src/
│ ├── components/ # Reusable UI components
│ ├── screens/ # Screen-level components
│ ├── navigation/ # Navigation setup
│ ├── services/ # API calls, storage, etc.
│ ├── hooks/ # Custom React hooks
│ ├── utils/ # Helper functions
│ ├── constants/ # Colors, sizes, config
│ ├── types/ # TypeScript types
│ └── App.tsx # Root component
├── android/ # Native Android code
├── ios/ # Native iOS code
├── assets/ # Images, fonts, etc.
└── package.json请始终按照以下经过验证的结构组织React Native项目:
my-app/
├── src/
│ ├── components/ # 可复用UI组件
│ ├── screens/ # 屏幕级组件
│ ├── navigation/ # 导航设置
│ ├── services/ # API调用、存储等
│ ├── hooks/ # 自定义React钩子
│ ├── utils/ # 辅助函数
│ ├── constants/ # 颜色、尺寸、配置
│ ├── types/ # TypeScript类型
│ └── App.tsx # 根组件
├── android/ # 原生Android代码
├── ios/ # 原生iOS代码
├── assets/ # 图片、字体等
└── package.jsonQuick Start Patterns
快速入门模式
Basic Screen Component
基础屏幕组件
typescript
import React from 'react';
import { View, Text, StyleSheet, SafeAreaView } from 'react-native';
export const HomeScreen = () => {
return (
<SafeAreaView style={styles.container}>
<View style={styles.content}>
<Text style={styles.title}>Welcome</Text>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
content: {
flex: 1,
padding: 16,
},
title: {
fontSize: 24,
fontWeight: 'bold',
},
});typescript
import React from 'react';
import { View, Text, StyleSheet, SafeAreaView } from 'react-native';
export const HomeScreen = () => {
return (
<SafeAreaView style={styles.container}>
<View style={styles.content}>
<Text style={styles.title}>Welcome</Text>
</View>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
content: {
flex: 1,
padding: 16,
},
title: {
fontSize: 24,
fontWeight: 'bold',
},
});React Navigation Setup
React Navigation 设置
typescript
// navigation/AppNavigator.tsx
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
export const AppNavigator = () => (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);typescript
// navigation/AppNavigator.tsx
import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator();
export const AppNavigator = () => (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>
</NavigationContainer>
);Tab Navigation
标签页导航
typescript
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/Ionicons';
const Tab = createBottomTabNavigator();
export const TabNavigator = () => (
<Tab.Navigator>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: ({ color, size }) => (
<Icon name="home" size={size} color={color} />
),
}}
/>
</Tab.Navigator>
);typescript
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/Ionicons';
const Tab = createBottomTabNavigator();
export const TabNavigator = () => (
<Tab.Navigator>
<Tab.Screen
name="Home"
component={HomeScreen}
options={{
tabBarIcon: ({ color, size }) => (
<Icon name="home" size={size} color={color} />
),
}}
/>
</Tab.Navigator>
);Essential Patterns
关键模式
FlatList with Optimization
优化后的FlatList
typescript
<FlatList
data={items}
renderItem={({ item }) => <ItemCard item={item} />}
keyExtractor={item => item.id}
// Performance optimizations
removeClippedSubviews={true}
maxToRenderPerBatch={10}
updateCellsBatchingPeriod={50}
windowSize={21}
// Pull to refresh
onRefresh={handleRefresh}
refreshing={isRefreshing}
// Empty state
ListEmptyComponent={<EmptyState />}
/>typescript
<FlatList
data={items}
renderItem={({ item }) => <ItemCard item={item} />}
keyExtractor={item => item.id}
// 性能优化
removeClippedSubviews={true}
maxToRenderPerBatch={10}
updateCellsBatchingPeriod={50}
windowSize={21}
// 下拉刷新
onRefresh={handleRefresh}
refreshing={isRefreshing}
// 空状态
ListEmptyComponent={<EmptyState />}
/>Custom Hooks
自定义钩子
typescript
// hooks/useAsync.ts
export const useAsync = <T,>(asyncFn: () => Promise<T>) => {
const [state, setState] = useState({
loading: true,
data: null as T | null,
error: null as Error | null,
});
useEffect(() => {
asyncFn()
.then(data => setState({ loading: false, data, error: null }))
.catch(error => setState({ loading: false, data: null, error }));
}, []);
return state;
};typescript
// hooks/useAsync.ts
export const useAsync = <T,>(asyncFn: () => Promise<T>) => {
const [state, setState] = useState({
loading: true,
data: null as T | null,
error: null as Error | null,
});
useEffect(() => {
asyncFn()
.then(data => setState({ loading: false, data, error: null }))
.catch(error => setState({ loading: false, data: null, error }));
}, []);
return state;
};Responsive Styles
响应式样式
typescript
import { Dimensions, Platform } from 'react-native';
const { width, height } = Dimensions.get('window');
const styles = StyleSheet.create({
container: {
padding: width > 600 ? 32 : 16, // Tablet vs phone
},
text: {
fontSize: Platform.select({ ios: 16, android: 14 }),
},
});typescript
import { Dimensions, Platform } from 'react-native';
const { width, height } = Dimensions.get('window');
const styles = StyleSheet.create({
container: {
padding: width > 600 ? 32 : 16, // 平板 vs 手机
},
text: {
fontSize: Platform.select({ ios: 16, android: 14 }),
},
});Animated Components
动画组件
typescript
import Animated, {
useAnimatedStyle,
withSpring,
useSharedValue
} from 'react-native-reanimated';
const MyComponent = () => {
const offset = useSharedValue(0);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: withSpring(offset.value) }],
}));
return <Animated.View style={animatedStyle} />;
};typescript
import Animated, {
useAnimatedStyle,
withSpring,
useSharedValue
} from 'react-native-reanimated';
const MyComponent = () => {
const offset = useSharedValue(0);
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateX: withSpring(offset.value) }],
}));
return <Animated.View style={animatedStyle} />;
};State Management
状态管理
Context API Pattern
Context API 模式
typescript
// contexts/AuthContext.tsx
interface AuthContextType {
user: User | null;
login: (credentials: Credentials) => Promise<void>;
logout: () => void;
}
const AuthContext = createContext<AuthContextType>(null!);
export const AuthProvider: React.FC<{children: React.ReactNode}> = ({children}) => {
const [user, setUser] = useState<User | null>(null);
const login = async (credentials: Credentials) => {
const user = await authService.login(credentials);
setUser(user);
};
const logout = () => setUser(null);
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => useContext(AuthContext);typescript
// contexts/AuthContext.tsx
interface AuthContextType {
user: User | null;
login: (credentials: Credentials) => Promise<void>;
logout: () => void;
}
const AuthContext = createContext<AuthContextType>(null!);
export const AuthProvider: React.FC<{children: React.ReactNode}> = ({children}) => {
const [user, setUser] = useState<User | null>(null);
const login = async (credentials: Credentials) => {
const user = await authService.login(credentials);
setUser(user);
};
const logout = () => setUser(null);
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => useContext(AuthContext);Redux Toolkit Integration
Redux Toolkit 集成
typescript
import { configureStore, createSlice } from '@reduxjs/toolkit';
const userSlice = createSlice({
name: 'user',
initialState: { profile: null },
reducers: {
setProfile: (state, action) => {
state.profile = action.payload;
},
},
});
export const store = configureStore({
reducer: {
user: userSlice.reducer,
},
});typescript
import { configureStore, createSlice } from '@reduxjs/toolkit';
const userSlice = createSlice({
name: 'user',
initialState: { profile: null },
reducers: {
setProfile: (state, action) => {
state.profile = action.payload;
},
},
});
export const store = configureStore({
reducer: {
user: userSlice.reducer,
},
});Platform-Specific Code
平台专属代码
Conditional Rendering
条件渲染
typescript
import { Platform } from 'react-native';
const Component = () => (
<>
{Platform.OS === 'ios' && <IOSComponent />}
{Platform.OS === 'android' && <AndroidComponent />}
</>
);typescript
import { Platform } from 'react-native';
const Component = () => (
<>
{Platform.OS === 'ios' && <IOSComponent />}
{Platform.OS === 'android' && <AndroidComponent />}
</>
);File Extensions
文件扩展名
Create platform-specific files:
- - iOS only
Component.ios.tsx - - Android only
Component.android.tsx - - Shared fallback
Component.tsx
创建平台专属文件:
- - 仅iOS
Component.ios.tsx - - 仅Android
Component.android.tsx - - 共享回退文件
Component.tsx
Performance Best Practices
性能最佳实践
Memoization
记忆化
typescript
const Item = React.memo(({ item }) => (
<View><Text>{item.name}</Text></View>
));
const computedValue = useMemo(() =>
expensiveCalculation(data),
[data]
);
const handlePress = useCallback(() => {
doSomething(id);
}, [id]);typescript
const Item = React.memo(({ item }) => (
<View><Text>{item.name}</Text></View>
));
const computedValue = useMemo(() =>
expensiveCalculation(data),
[data]
);
const handlePress = useCallback(() => {
doSomething(id);
}, [id]);Image Optimization
图片优化
typescript
<Image
source={{ uri: imageUrl }}
style={styles.image}
resizeMode="cover"
// Cache control
defaultSource={require('../assets/placeholder.png')}
/>typescript
<Image
source={{ uri: imageUrl }}
style={styles.image}
resizeMode="cover"
// 缓存控制
defaultSource={require('../assets/placeholder.png')}
/>Native Module Integration
原生模块集成
Linking Native Libraries
链接原生库
bash
undefinedbash
undefinedAuto-linking (RN 0.60+)
自动链接(RN 0.60+)
npm install react-native-library
cd ios && pod install
npm install react-native-library
cd ios && pod install
Manual linking (older versions)
手动链接(旧版本)
react-native link react-native-library
undefinedreact-native link react-native-library
undefinedPermissions Handling
权限处理
typescript
import { PermissionsAndroid, Platform } from 'react-native';
const requestCameraPermission = async () => {
if (Platform.OS === 'android') {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
}
return true; // iOS handles via Info.plist
};typescript
import { PermissionsAndroid, Platform } from 'react-native';
const requestCameraPermission = async () => {
if (Platform.OS === 'android') {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.CAMERA
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
}
return true; // iOS通过Info.plist处理
};Common Utilities
常用工具
Storage Helper
存储助手
typescript
import AsyncStorage from '@react-native-async-storage/async-storage';
export const storage = {
get: async (key: string) => {
const value = await AsyncStorage.getItem(key);
return value ? JSON.parse(value) : null;
},
set: async (key: string, value: any) => {
await AsyncStorage.setItem(key, JSON.stringify(value));
},
remove: async (key: string) => {
await AsyncStorage.removeItem(key);
},
};typescript
import AsyncStorage from '@react-native-async-storage/async-storage';
export const storage = {
get: async (key: string) => {
const value = await AsyncStorage.getItem(key);
return value ? JSON.parse(value) : null;
},
set: async (key: string, value: any) => {
await AsyncStorage.setItem(key, JSON.stringify(value));
},
remove: async (key: string) => {
await AsyncStorage.removeItem(key);
},
};API Service
API 服务
typescript
// services/api.ts
const API_BASE = 'https://api.example.com';
export const api = {
get: async <T>(endpoint: string): Promise<T> => {
const response = await fetch(`${API_BASE}${endpoint}`);
if (!response.ok) throw new Error('Request failed');
return response.json();
},
post: async <T>(endpoint: string, data: any): Promise<T> => {
const response = await fetch(`${API_BASE}${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
return response.json();
},
};typescript
// services/api.ts
const API_BASE = 'https://api.example.com';
export const api = {
get: async <T>(endpoint: string): Promise<T> => {
const response = await fetch(`${API_BASE}${endpoint}`);
if (!response.ok) throw new Error('Request failed');
return response.json();
},
post: async <T>(endpoint: string, data: any): Promise<T> => {
const response = await fetch(`${API_BASE}${endpoint}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
});
return response.json();
},
};Debugging Tips
调试技巧
React Native Debugger
React Native 调试器
typescript
// Enable in development
if (__DEV__) {
console.log('Development mode');
// Access dev menu: Cmd+D (iOS) or Cmd+M (Android)
}typescript
// 开发环境启用
if (__DEV__) {
console.log('Development mode');
// 打开开发菜单:Cmd+D(iOS)或 Cmd+M(Android)
}Performance Monitoring
性能监控
typescript
import { InteractionManager } from 'react-native';
InteractionManager.runAfterInteractions(() => {
// Expensive task after animations complete
});typescript
import { InteractionManager } from 'react-native';
InteractionManager.runAfterInteractions(() => {
// 动画完成后执行耗时任务
});TypeScript Integration
TypeScript 集成
Navigation Types
导航类型
typescript
type RootStackParamList = {
Home: undefined;
Profile: { userId: string };
Settings: undefined;
};
type HomeScreenProps = NativeStackScreenProps<RootStackParamList, 'Home'>;typescript
type RootStackParamList = {
Home: undefined;
Profile: { userId: string };
Settings: undefined;
};
type HomeScreenProps = NativeStackScreenProps<RootStackParamList, 'Home'>;Component Props
组件属性
typescript
interface ButtonProps {
title: string;
onPress: () => void;
variant?: 'primary' | 'secondary';
disabled?: boolean;
}
const Button: React.FC<ButtonProps> = ({ title, onPress, variant = 'primary', disabled }) => {
// Component implementation
};typescript
interface ButtonProps {
title: string;
onPress: () => void;
variant?: 'primary' | 'secondary';
disabled?: boolean;
}
const Button: React.FC<ButtonProps> = ({ title, onPress, variant = 'primary', disabled }) => {
// 组件实现
};Testing Considerations
测试注意事项
When building React Native apps, structure code to be testable:
- Extract business logic into pure functions
- Use dependency injection for services
- Keep components simple and presentational
- Test navigation separately from component logic
构建React Native应用时,应确保代码结构便于测试:
- 将业务逻辑提取为纯函数
- 对服务使用依赖注入
- 保持组件简洁,专注于展示
- 单独测试导航逻辑与组件逻辑
Build Configuration
构建配置
Environment Variables
环境变量
typescript
// config/env.ts
export const config = {
API_URL: __DEV__
? 'http://localhost:3000'
: 'https://api.production.com',
FEATURE_FLAGS: {
newUI: true,
},
};typescript
// config/env.ts
export const config = {
API_URL: __DEV__
? 'http://localhost:3000'
: 'https://api.production.com',
FEATURE_FLAGS: {
newUI: true,
},
};Additional Resources
额外资源
For detailed component patterns, styling guidelines, and advanced topics, see the reference files in the directory:
references/- - Detailed component patterns and examples
component-patterns.md - - Comprehensive styling best practices
styling-guide.md - - Advanced optimization techniques
performance.md
如需了解详细的组件模式、样式指南和进阶主题,请查看目录下的参考文件:
references/- - 详细的组件模式和示例
component-patterns.md - - 全面的样式最佳实践
styling-guide.md - - 进阶优化技巧
performance.md