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

React Native实现页面跳转按钮及动态按钮替代方案问询

问题修复与替代方案

一、先修复当前按钮的跳转问题

你的代码里有两个明显问题导致跳转异常:

  1. onPress 里同时调用了 Nav() 和 Nav1(),不管点哪个按钮都会同时跳两个页面
  2. 样式里的 boarderColor 是拼写错误,应该是 borderColor

修改后的代码如下:

import { StyleSheet, TouchableOpacity, Text, View } from 'react-native'
import React, { useState } from 'react'
import { Colors } from '../constants'
import { useNavigation } from '@react-navigation/native'

export const GroupofButtons = ({ buttons }) => {
    const navigation = useNavigation();
    const [clickedId, setClickedId] = useState(0);

    // 根据按钮索引判断跳转目标
    const handleButtonPress = (index) => {
        setClickedId(index);
        if (index === 0) {
            navigation.navigate("ChatsPage");
        } else if (index === 1) {
            navigation.navigate("CallingScreen");
        }
    }

    return (
        <View style={styles.container}>
            {
                buttons.map((buttonsLabel, index) => {
                    return (
                        <TouchableOpacity
                            onPress={() => handleButtonPress(index)}
                            key={index}
                            style={[
                                index === clickedId ? styles.buttonActive : styles.buttons,
                            ]}>
                            <Text
                                style={index === clickedId ? styles.textActive : styles.text}>
                                {buttonsLabel}
                            </Text>
                        </TouchableOpacity>
                    )
                })
            }
        </View>
    )
}

const styles = StyleSheet.create({
    container: {
        padding: 10,
        flexDirection: 'row',
    },
    buttons: {
        height: 25,
        width: 55,
        marginLeft: 10,
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: 'white',
        borderRadius: 7,
        borderWidth: 1,
        borderColor: Colors.primary, // 修复拼写错误
    },
    buttonActive: {
        height: 25,
        width: 55,
        marginLeft: 10,
        alignItems: 'center',
        justifyContent: 'center',
        borderRadius: 7,
        backgroundColor: Colors.primary,
    },
    textActive: {
        color: 'white',
    },
    text: {
        color: 'black',
    },
})

如果想让组件更通用,不用硬编码索引,可以把按钮配置改成包含路由名的数组,比如父组件传 buttons = [{label: '聊天', route: 'ChatsPage'}, {label: '通话', route: 'CallingScreen'}],组件里这样处理:

export const GroupofButtons = ({ buttons }) => {
    const navigation = useNavigation();
    const [activeRoute, setActiveRoute] = useState(buttons[0].route);

    const handleButtonPress = (route) => {
        setActiveRoute(route);
        navigation.navigate(route);
    }

    return (
        <View style={styles.container}>
            {
                buttons.map(({label, route}) => {
                    return (
                        <TouchableOpacity
                            onPress={() => handleButtonPress(route)}
                            key={route}
                            style={[
                                route === activeRoute ? styles.buttonActive : styles.buttons,
                            ]}>
                            <Text
                                style={route === activeRoute ? styles.textActive : styles.text}>
                                {label}
                            </Text>
                        </TouchableOpacity>
                    )
                })
            }
        </View>
    )
}

二、动态按钮的替代方案

方案1:使用React Native Paper的SegmentedButtons

如果不想自己写样式,可以用现成的UI库,自带激活状态切换,用法简单:

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

export const GroupofButtons = () => {
  const navigation = useNavigation();
  const [selectedValue, setSelectedValue] = useState('chat');

  return (
    <SegmentedButtons
      values={['chat', 'call']}
      selectedValue={selectedValue}
      onValueChange={(value) => {
        setSelectedValue(value);
        if (value === 'chat') {
            navigation.navigate('ChatsPage');
        } else {
            navigation.navigate('CallingScreen');
        }
      }}
      labels={{
        chat: '聊天',
        call: '通话',
      }}
    />
  );
};

方案2:自定义通用Tab组件

如果需要完全自定义样式,可以写一个更通用的Tab组件,支持传入任意按钮配置:

import { StyleSheet, TouchableOpacity, Text, View } from 'react-native'
import React, { useState } from 'react'
import { Colors } from '../constants'
import { useNavigation } from '@react-navigation/native'

export const CustomTabButtons = ({ tabs = [] }) => {
    const navigation = useNavigation();
    const [activeTab, setActiveTab] = useState(tabs[0]?.key || '');

    return (
        <View style={styles.tabContainer}>
            {tabs.map(tab => (
                <TouchableOpacity
                    key={tab.key}
                    onPress={() => {
                        setActiveTab(tab.key);
                        navigation.navigate(tab.route);
                    }}
                    style={[
                        styles.tabButton,
                        activeTab === tab.key && styles.activeTabButton
                    ]}
                >
                    <Text style={[
                        styles.tabText,
                        activeTab === tab.key && styles.activeTabText
                    ]}>
                        {tab.label}
                    </Text>
                </TouchableOpacity>
            ))}
        </View>
    )
}

const styles = StyleSheet.create({
    tabContainer: {
        flexDirection: 'row',
        paddingHorizontal: 10,
        paddingVertical: 8,
        gap: 10,
    },
    tabButton: {
        flex: 1,
        paddingVertical: 6,
        borderRadius: 8,
        backgroundColor: '#fff',
        borderWidth: 1,
        borderColor: Colors.primary,
        alignItems: 'center',
    },
    activeTabButton: {
        backgroundColor: Colors.primary,
        borderColor: Colors.primary,
    },
    tabText: {
        color: '#000',
        fontSize: 14,
    },
    activeTabText: {
        color: '#fff',
        fontWeight: '500',
    },
})

// 使用时在父组件传入:
// <CustomTabButtons 
//   tabs={[
//     {key: 'chat', label: '聊天', route: 'ChatsPage'},
//     {key: 'call', label: '通话', route: 'CallingScreen'}
//   ]}
// />

方案3:使用@react-navigation/material-top-tabs

如果你的页面本身是Tab导航的一部分,可以直接用React Navigation的顶部Tab组件,自带路由跳转和状态管理:

import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';
import ChatsPage from './ChatsPage';
import CallingScreen from './CallingScreen';

const Tab = createMaterialTopTabNavigator();

export const TabNavigator = () => {
  return (
    <Tab.Navigator
      screenOptions={{
        tabBarLabelStyle: { fontSize: 14 },
        tabBarStyle: { backgroundColor: '#fff' },
        tabBarActiveTintColor: Colors.primary,
        tabBarInactiveTintColor: '#000',
        tabBarIndicatorStyle: { backgroundColor: Colors.primary },
      }}
    >
      <Tab.Screen name="ChatsPage" component={ChatsPage} options={{ title: '聊天' }} />
      <Tab.Screen name="CallingScreen" component={CallingScreen} options={{ title: '通话' }} />
    </Tab.Navigator>
  );
};

内容的提问来源于stack exchange,提问作者Star Lord

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:45:49