React Native Expo应用中Stack与底部导航器结合使用及异常排查
问题原因
- 重复嵌套
NavigationContainer:React Navigation要求全局只能存在一个顶层NavigationContainer,你编写的StackN.js内部已经包裹了一层NavigationContainer,在ClubDetailScreen中引入时又额外套了一层,同时ClubDetailScreen本身已经处于底部Tab对应的根导航容器下,多层容器嵌套会导致子导航的渲染逻辑异常。 - 布局缺失
flex:1属性:ClubDetailScreen的最外层View、包裹ScrollView和StackN的父View都没有设置flex:1,导航容器默认需要占满可用空间才能渲染内容,无高度配置的情况下StackN的内容高度为0,自然看不到按钮。 - 导航结构逻辑错误:嵌套导航的正确逻辑是将Stack导航器直接作为底部Tab的某一项的页面组件,而非在普通的Tab页面内部再嵌入Stack导航器,你当前的结构相当于把Stack塞到了Tab的一个普通页面里,不符合导航库的设计规范。
- 测试代码逻辑bug:
ProfileScreen中第一个按钮的跳转逻辑是navigation.navigate('Profile'),也就是跳转到自身,即使导航正常运行点击也不会有变化,属于测试代码的小问题。
解决建议
- 首先修改
StackN.js代码,删除内部的NavigationContainer,直接导出Stack导航器本身:
// 修改后的StackN.js import * as React from 'react'; import { Button, View } from 'react-native'; import { createStackNavigator } from '@react-navigation/stack'; function HomeScreen({navigation}){ return ( <View style={{flex:1, alignItems: 'center', justifyContent: 'center'}}> <Button title="Go to Profile" onPress={()=>navigation.navigate('Profile')} /> </View> ); } function ProfileScreen({navigation}){ return ( <View style={{flex:1, alignItems: 'center', justifyContent: 'center'}}> {/* 这里跳转目标修正为你需要的页面,不要跳自身 */} <Button title="Go to Notifications" onPress={()=>navigation.navigate('Notifications')} /> <Button title="Go Back" onPress={()=>navigation.goBack()} /> </View> ); } const Stack = createStackNavigator(); function MyStack() { return( <Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} /> <Stack.Screen name="Profile" component={ProfileScreen} /> </Stack.Navigator> ); } // 直接导出Stack导航器,不要包NavigationContainer export default MyStack;
- 调整底部Tab导航的配置,把需要嵌套Stack的Tab项的
component直接设置为上面导出的MyStack,不需要额外套一层ClubDetailScreen,如果需要保留ClubDetailScreen作为Stack的默认首页,调整Stack的初始路由即可。 - 如果确实需要在
ClubDetailScreen中嵌入Stack,修改该页面的布局代码,给所有父级View添加flex:1,同时删除多余的NavigationContainer:
// 修改后的ClubDetailScreen核心渲染逻辑 const ClubDetailScreen = props => { return ( // 最外层View加flex:1 <View style={{flex:1}}> <HeaderComponent /> {/* 父容器加flex:1 */} <View style={{flex:1}}> <ScrollView style={{height:100}}> <Text>SCHERMATA NON DIRETTAMENTE COLLEGATA ALL'IMPLEMENTAZIONE ATTUALE : - TODO - </Text> </ScrollView> {/* 删除多余的NavigationContainer,直接渲染StackN */} <StackN /> </View> </View> ); }
内容的提问来源于stack exchange,提问作者64Bit1990
相关产品推荐
相关产品推荐

