React-native Stack 和 TabBottom 和 Drawer的 导航嵌套使用
说实话 RN 的文档,我表示看的很吃力
此文章为ReactNavigation导航库5.0版本的第4篇,前几篇系列文章如下:
React Navigation5.0系列一:StackNavigator的使用
React Navigation5.0系列二:TabNavigation的使用
React Navigation5.0系列三:Drawer navigation的使用
此前几篇系列文章,主要讲了StackNavigator, TavNavigation以及Drawer Navigation的使用讲解,现实中往往是不同的导航组件组合进行使用的,本篇文章主要讲解导航的嵌套使用及注意事项。
创建需要的页面
// 设置页面 const SettingsScreen = ({ navigation }) => { return (1, alignItems: 'center', justifyContent: 'center' }}> ) } // 首页 const HomeScreen = ({ navigation }) => { return (SettingScreen <Button title="Go to Details" onPress={() => navigation.navigate('Detail')} />1, alignItems: 'center', justifyContent: 'center' }}> ) } // 详情页 const DetailScreen = ({ navigation }) => { return (HomeScreen <Button title="Go to Details" onPress={() => navigation.navigate('Detail')} />1, alignItems: 'center', justifyContent: 'center' }}> ) }DetailScreen <Button title="Go to Detail Again" // onPress={() => navigation.navigate('Detail')} onPress={() => navigation.push('Detail')} />
创建三个对应的导航器实例
const Tab = createBottomTabNavigator(); // 选项卡页签tab navigator 实例 const RootStack = createStackNavigator(); // 堆栈stack 实例 const Drawer = createDrawerNavigator(); // 抽屉drawer实例
创建底部导航路由,采用系列二文章代码
function IconWithBadge({ icon, badgeCount, size }) { return (24, height: 24, margin: 5 }}> )} ); } function HomeIconWithBadge(props) { // You should pass down the badgeCount in some other ways like React Context API, Redux, MobX or event emitters. return{{ width: size, height: size }} /> {badgeCount > 0 && ( <View style={{ // On React Native < 0.57 overflow outside of parent will not work on Android, see https://git.io/fhLJ8 position: 'absolute', right: -6, top: -3, backgroundColor: 'red', borderRadius: 6, width: 12, height: 12, justifyContent: 'center', alignItems: 'center', }} > 'white', fontSize: 10, fontWeight: 'bold' }}> {badgeCount} 3} />; } const TabScreen = () => { return ( <Tab.Navigator headerMode='none' screenOptions={({ route }) => ({ tabBarIcon: ({ focused, color, size }) => { if (route.name === 'Home') { return ( <HomeIconWithBadge icon={ focused ? HomeIconActive : HomeIconNormal } size={size} color={color} /> ); } else if (route.name === 'Settings') { return ( <Image source={focused ? WorkIconActive : WorkIconNormal} style={{width: size, height: size}} /> ); } }, })} tabBarOptions={{ activeTintColor: 'tomato', inactiveTintColor: 'gray', }} > "Home" component={HomeScreen} /> "Settings" component={SettingsScreen} /> ) }
堆栈(Stack)与Tab嵌套
const rootRouteScreen = () => { return ('TabNav'}> ) }'TabNav' component={TabScreen} /> "Detail" component={DetailScreen} />
Stack Navigator, Tab Navigator与Drawer Navigator综合嵌套
const App = () => { return (); } "Home" drawerType='slide' drawerContent={(props) => } > 'root' component={rootRouteScreen} /> 'Setting' component={SettingsScreen} />
最后我们来看一下效果
嵌套导航的最佳实践
建议将嵌套做到最少,应该尝试采用尽可能少的嵌套来实现你的业务需求,因为多层嵌套会导致如下几个问题:
- 在多层嵌套的页面,代码难以维护
- 深度嵌套的视图层次结构,这可能会导致低端设备的内存和性能问题
- 嵌套相同类型的导航器(例如,选项卡内的选项卡,抽屉内的抽屉等)让用户的体验极差。