React Native鸿蒙开发实战(四):路由导航与多页面应用
一、React Navigation在鸿蒙平台的集成
在React Native鸿蒙应用中,页面导航是构建复杂应用的核心能力。React Navigation作为React Native生态中最流行的导航库,在鸿蒙平台上需要特殊的配置和适配。
1.1 安装与基础配置
首先安装React Navigation核心库及其依赖:
npm install @react-navigation/native @react-navigation/stack
npm install react-native-gesture-handler react-native-reanimated
npm install react-native-screens react-native-safe-area-context
针对鸿蒙平台的特定配置,需要在metro.config.js中添加对React Navigation的支持:
const { createHarmonyMetroConfig } = require('@react-native-oh/react-native-harmony/metro.config');
module.exports = mergeConfig(
getDefaultConfig(__dirname),
createHarmonyMetroConfig({
// 启用React Navigation的鸿蒙适配
extraNodeModules: {
'@react-navigation': require.resolve('@react-navigation/native'),
},
})
);
1.2 导航容器初始化
创建全局导航引用,这是处理导航初始化的关键步骤:
import { createNavigationContainerRef } from '@react-navigation/native';
export const navigationRef = createNavigationContainerRef();
export function navigate(name, params) {
if (navigationRef.isReady()) {
navigationRef.navigate(name, params);
} else {
setTimeout(() => navigate(name, params), 100);
}
}
二、堆栈导航器深度解析
堆栈导航器模拟了原生应用的页面堆栈行为,提供熟悉的页面切换体验。
2.1 基础堆栈配置
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
function AppNavigator() {
return (
<NavigationContainer ref={navigationRef}>
<Stack.Navigator
initialRouteName="Home"
screenOptions={{
headerStyle: { backgroundColor: '#007AFF' },
headerTintColor: '#fff',
gestureEnabled: true,
}}
>
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ title: '首页' }}
/>
<Stack.Screen
name="Details"
component={DetailScreen}
options={{ title: '详情页' }}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
2.2 导航操作详解
在组件中,可以通过navigationprop进行各种导航操作:
function HomeScreen({ navigation }) {
return (
<View style={styles.container}>
<Button
title="跳转到详情页"
onPress={() => navigation.navigate('Details', { itemId: 123 })}
/>
<Button
title="替换当前页"
onPress={() => navigation.replace('Details')}
/>
<Button
title="打开模态框"
onPress={() => navigation.push('Modal')}
/>
</View>
);
}
关键导航方法:
navigate(): 跳转到指定页面,如果页面已在栈中则跳转到该实例push(): 总是创建新页面实例并压入栈顶replace(): 用新页面替换当前页面goBack(): 返回上一页popToTop(): 返回堆栈中的第一个页面
三、参数传递与类型安全
页面间参数传递是多页面应用的核心需求,需要确保类型安全和错误处理。
3.1 安全的参数传递模式
// 定义参数类型接口
type RootStackParamList = {
Home: undefined;
Details: {
itemId: string;
title?: string;
timestamp: number;
};
Profile: { userId: string };
};
const Stack = createStackNavigator<RootStackParamList>();
// 发送参数
navigation.navigate('Details', {
itemId: 'HM001',
title: '鸿蒙开发指南',
timestamp: Date.now()
});
// 接收参数
function DetailScreen({ route, navigation }) {
// 使用默认值避免undefined错误
const { itemId, title = '默认标题', timestamp } = route.params ?? {};
return (
<View>
<Text>商品ID: {itemId}</Text>
<Text>标题: {title}</Text>
<Text>时间: {new Date(timestamp).toLocaleString()}</Text>
</View>
);
}
3.2 参数验证与错误处理
import { useEffect } from 'react';
function DetailScreen({ route, navigation }) {
useEffect(() => {
// 参数验证
if (!route.params?.itemId) {
console.warn('缺少必要的itemId参数');
navigation.goBack(); // 参数不完整时返回
return;
}
// 设置动态标题
navigation.setOptions({
title: route.params.title || '详情页'
});
}, [route.params, navigation]);
// 渲染内容...
}
四、标签导航与抽屉导航
除了堆栈导航,React Navigation还提供其他导航模式满足不同场景需求。
4.1 标签导航器
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
const Tab = createBottomTabNavigator();
function TabNavigator() {
return (
<Tab.Navigator
screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {
let iconName;
if (route.name === 'Home') {
iconName = focused ? 'home' : 'home-outline';
} else if (route.name === 'Settings') {
iconName = focused ? 'settings' : 'settings-outline';
}
return <Ionicons name={iconName} size={size} color={color} />;
},
tabBarActiveTintColor: '#007AFF',
tabBarInactiveTintColor: 'gray',
})}
>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
);
}
4.2 嵌套导航实践
复杂的应用通常需要嵌套多种导航器:
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
// 标签页内部的堆栈导航
function HomeStack() {
return (
<Stack.Navigator>
<Stack.Screen name="HomeMain" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailScreen} />
</Stack.Navigator>
);
}
// 主导航结构
function AppNavigator() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="首页" component={HomeStack} />
<Tab.Screen name="个人中心" component={ProfileStack} />
</Tab.Navigator>
</NavigationContainer>
);
}
五、鸿蒙特定导航适配
在鸿蒙平台上,需要特别注意导航的性能优化和平台特性适配。
5.1 性能优化策略
// 懒加载页面组件优化性能
const HomeScreen = React.lazy(() => import('./screens/HomeScreen'));
const DetailScreen = React.lazy(() => import('./screens/DetailScreen'));
// 封装懒加载组件
function LazyComponent({ component: Component, ...props }) {
return (
<React.Suspense fallback={<ActivityIndicator size="large" />}>
<Component {...props} />
</React.Suspense>
);
}
// 在导航器中使用
<Stack.Screen
name="Details"
component={(props) => <LazyComponent component={DetailScreen} {...props} />}
/>
5.2 鸿蒙返回手势处理
import { BackHandler } from 'react-native';
function DetailScreen({ navigation }) {
useEffect(() => {
const backHandler = BackHandler.addEventListener(
'hardwareBackPress',
() => {
if (navigation.canGoBack()) {
navigation.goBack();
return true;
}
return false;
}
);
return () => backHandler.remove();
}, [navigation]);
// 处理鸿蒙特定的返回逻辑
const handleHarmonyBack = () => {
// 鸿蒙特定的返回处理逻辑
if (/* 特定条件 */) {
navigation.popToTop();
} else {
navigation.goBack();
}
};
}
六、实战案例:电商应用导航
下面是一个完整的电商应用导航实例,展示如何整合各种导航模式。
import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
// 页面组件
const HomeScreen = ({ navigation }) => (
<View>
<Button
title="商品列表"
onPress={() => navigation.navigate('ProductList')}
/>
<Button
title="促销活动"
onPress={() => navigation.navigate('Promotion')}
/>
</View>
);
const ProductDetailScreen = ({ route }) => {
const { productId } = route.params;
return <Text>商品详情: {productId}</Text>;
};
// 创建导航器
const HomeStack = createStackNavigator();
const Tab = createBottomTabNavigator();
function HomeStackNavigator() {
return (
<HomeStack.Navigator>
<HomeStack.Screen name="Home" component={HomeScreen} />
<HomeStack.Screen name="ProductList" component={ProductListScreen} />
<HomeStack.Screen name="ProductDetail" component={ProductDetailScreen} />
</HomeStack.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="首页" component={HomeStackNavigator} />
<Tab.Screen name="购物车" component={CartScreen} />
<Tab.Screen name="我的" component={ProfileScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
export default App;
七、总结
通过本章学习,我们掌握了在React Native鸿蒙应用中实现复杂导航的完整方案。核心要点总结:
- 导航基础:React Navigation提供了堆栈、标签、抽屉三种主流导航模式
- 参数传递:类型安全的参数传递是确保应用稳定性的关键
- 嵌套导航:合理组合不同导航器可以构建复杂的应用结构
- 鸿蒙适配:需要特别注意性能优化和平台特性兼容
最佳实践建议:
- 使用TypeScript确保导航参数的类型安全
- 实现懒加载优化大型应用的启动性能
- 统一处理鸿蒙平台的返回手势和导航逻辑
- 建立全局导航引用解决初始化时序问题
下一章我们将深入讲解网络请求与API交互,学习如何在React Native鸿蒙应用中高效处理数据获取和状态管理。