React Native实现页面跳转按钮及动态按钮替代方案问询
问题修复与替代方案
一、先修复当前按钮的跳转问题
你的代码里有两个明显问题导致跳转异常:
onPress里同时调用了Nav()和Nav1(),不管点哪个按钮都会同时跳两个页面- 样式里的
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
相关产品推荐
相关产品推荐

