You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native BottomTabBar内组件跳转新页面并传参问题

React Native 导航跳转与参数传递解决方案

问题场景

当前项目基于@react-navigation/bottom-tabs实现底部导航,ListScreen内部又嵌套了顶部Tab导航。需要在AllScreen组件中完成两个跳转需求:

  • 点击右侧箭头图标跳转到DetailsScreen,同时传递provincia参数
  • 点击CardResturant卡片跳转到餐厅详情页,传递对应餐厅信息参数

现有代码结构

App.js 底部导航配置

const Navigator = ()=> {
    return(
        <NavigationContainer>
            <Tab.Navigator
            initialRouteName={homeName}
            >
                <Tab.Screen name={homeName} component={HomeScreen} options={{ headerShown: false, tabBarIcon:()=>(<Icon name="home" size={25}/>)}}/>
                <Tab.Screen name={listName} component={ListScreen} options={{headerShown: false, tabBarIcon:()=>(<Icon name="list" size={20}/>)}}/>
                <Tab.Screen name={perizieName} component={PeritiScreen} options={{ headerShown: false, tabBarIcon:()=>(<Icon name="laptop" size={25}/>) }}/>
            </Tab.Navigator>
        </NavigationContainer>
    );
}

ListScreen 内部嵌套顶部Tab

const ListScreen = ()=>{
    return(
        <SafeAreaView style={{flex:1}}>
            <Tab.Navigator
            swipeEnabled={false}
            initialRouteName="Lista completa"
            style={style.topTap}
            >
                <Tab.Screen name="Mappa" component={MapScreen} />
                <Tab.Screen name="Lista completa" component={AllScreen} /> {/* 跳转逻辑所在组件 */}
            </Tab.Navigator>
        </SafeAreaView>
    );
};

AllScreen 待修改组件

<SafeAreaView>
    <View style={style.searchContainer}>
        <Text style={{paddingLeft:10}}>
            <Icon name="search" size={25} color={COLORS.grey} />
        </Text>
        <TextInput placeholder="Cerca provincia" style={{fontSize:20, paddingLeft:10}} />
    </View>
    <ScrollView>
    {
        masterList.map((provincia)=>{
            return(
                <View>
                    <View style={{flexDirection:"row"}}>
                        <View>
                            <Text style={style.provincia}>
                                {provincia.nome}
                            </Text>
                            <Text style={{marginLeft:10, fontSize: 12, color:COLORS.grey, marginBottom:5}}>Ristoranti consigliati nella provincia di {provincia.nome},{"\n"}selezione quello che preferisci</Text>
                        </View>
                        <View style={{alignSelf:"center", alignItems:"center", paddingLeft: "18%"}}>
                            <Icon 
                            onPress={"i need to go to DetailsScreen"} {/* 需修改此处 */}
                            name="arrow-right" size={20} />
                        </View>
                    </View>
                    <ScrollView
                    horizontal={true}
                    showsHorizontalScrollIndicator={false}
                    >
                        {
                            provincia.ristoranti.map((ristorante)=>{
                                return(
                                    <CardResturant
                                    resturant = {ristorante}
                                    /> {/* 需给卡片添加跳转 */}
                                )
                            })
                        }
                    </ScrollView>
                </View>
        )})
    }
    </ScrollView>
</SafeAreaView>

分步解决方案

1. 调整嵌套导航结构

因为要实现页面跳转,需要将ListScreen的内部Tab导航包裹在StackNavigator中,确保跳转路径存在:

import { createStackNavigator } from '@react-navigation/stack';

const Stack = createStackNavigator();

// 原Tab导航抽离为独立组件
const ListTabNavigator = () => {
    return(
        <Tab.Navigator
            swipeEnabled={false}
            initialRouteName="Lista completa"
            style={style.topTap}
        >
            <Tab.Screen name="Mappa" component={MapScreen} />
            <Tab.Screen name="Lista completa" component={AllScreen} />
        </Tab.Navigator>
    );
};

// 修改ListScreen为栈嵌套Tab结构
const ListScreen = ()=>{
    return(
        <Stack.Navigator>
            <Stack.Screen 
                name="ListTab" 
                component={ListTabNavigator} 
                options={{headerShown: false}} 
            />
            <Stack.Screen name="DetailsScreen" component={DetailsScreen} />
            <Stack.Screen name="RestaurantDetailScreen" component={RestaurantDetailScreen} />
        </Stack.Navigator>
    );
};

2. 在AllScreen中实现跳转逻辑

导入useNavigation钩子,为箭头和卡片添加点击事件并传递参数:

import { useNavigation } from '@react-navigation/native';

const AllScreen = () => {
    const navigation = useNavigation();

    return(
        <SafeAreaView>
            {/* 原有搜索栏代码 */}
            <ScrollView>
            {
                masterList.map((provincia)=>{
                    return(
                        <View key={provincia.id}> {/* 必须添加唯一key */}
                            <View style={{flexDirection:"row"}}>
                                {/* 原有省份信息代码 */}
                                <View style={{alignSelf:"center", alignItems:"center", paddingLeft: "18%"}}>
                                    <Icon 
                                        onPress={() => {
                                            // 跳转到省份详情页并传参
                                            navigation.navigate('DetailsScreen', { provincia });
                                        }}
                                        name="arrow-right" size={20} 
                                    />
                                </View>
                            </View>
                            <ScrollView
                                horizontal={true}
                                showsHorizontalScrollIndicator={false}
                            >
                                {
                                    provincia.ristoranti.map((ristorante)=>{
                                        return(
                                            <CardResturant
                                                key={ristorante.id}
                                                resturant={ristorante}
                                                onPress={() => {
                                                    // 跳转到餐厅详情页并传参
                                                    navigation.navigate('RestaurantDetailScreen', { ristorante });
                                                }}
                                            />
                                        )
                                    })
                                }
                            </ScrollView>
                        </View>
                    )})
            }
            </ScrollView>
        </SafeAreaView>
    );
};

3. 修改CardResturant组件支持点击

确保卡片组件使用可点击容器包裹,并接收onPress回调:

import { TouchableOpacity } from 'react-native';

const CardResturant = ({ resturant, onPress }) => {
    return(
        <TouchableOpacity 
            style={/* 你的卡片样式 */}
            onPress={onPress}
        >
            {/* 卡片内部内容:餐厅名称、图片等 */}
            <Text>{resturant.nome}</Text>
            {/* 其他卡片元素 */}
        </TouchableOpacity>
    );
};

4. 在详情页接收参数

使用useRoute钩子获取传递的参数:

import { useRoute } from '@react-navigation/native';

// 省份详情页
const DetailsScreen = () => {
    const route = useRoute();
    const { provincia } = route.params;

    return(
        <SafeAreaView>
            <Text>省份详情:{provincia.nome}</Text>
            {/* 使用provincia数据渲染页面 */}
        </SafeAreaView>
    );
};

// 餐厅详情页
const RestaurantDetailScreen = () => {
    const route = useRoute();
    const { ristorante } = route.params;

    return(
        <SafeAreaView>
            <Text>餐厅详情:{ristorante.nome}</Text>
            {/* 使用ristorante数据渲染页面 */}
        </SafeAreaView>
    );
};

关键注意事项

  • 嵌套导航中,子导航的页面跳转必须依赖父级栈导航,因此必须用StackNavigator包裹内部Tab导航
  • 所有列表渲染项必须添加唯一key属性,避免React警告
  • 卡片组件必须使用TouchableOpacity/Pressable等可点击组件,才能响应点击事件

内容的提问来源于stack exchange,提问作者Tommaso Ceredi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 22:54:34