React Native中Link与Pressable冲突:无法同时导航和切换图标颜色
解决思路
核心问题是嵌套Link与可点击组件导致事件冲突,且本地focused状态未和路由状态同步。改用命令式路由导航替代Link,在同一个点击事件里同时处理状态更新与页面跳转,再通过监听路由变化同步状态,确保无论通过哪种方式切换页面,图标颜色都能正确显示。
修改后的代码
import React, { useState, useEffect } from 'react'; import { View, StyleSheet, Dimensions, Pressable } from 'react-native'; import { useNavigate, useLocation } from 'react-router-native'; import { Text } from 'react-native-paper'; import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; export default function BottomBar() { const navigate = useNavigate(); const location = useLocation(); const [focused, setFocused] = useState(1); // 监听路由变化,同步更新底部栏选中状态 useEffect(() => { switch (location.pathname) { case '/escenas': setFocused(1); break; case '/settings': setFocused(2); break; case '/perfil': setFocused(3); break; case '/ajustes': setFocused(4); break; default: setFocused(1); } }, [location.pathname]); const tabColor = (tabIndex) => { return focused === tabIndex ? '#F29C46' : 'white'; }; return ( <View style={styles.container}> {/* 场景tab */} <Pressable onPress={() => { setFocused(1); navigate('/escenas'); }}> <View style={styles.tab}> <Icon name="movie-open" size={25} color={tabColor(1)} /> <Text style={[{ color: tabColor(1) }, styles.labelText]}>Escenas</Text> </View> </Pressable> {/* 社区tab */} <Pressable onPress={() => { setFocused(2); navigate('/settings'); }}> <View style={styles.tab}> <Icon name="account-group" size={25} color={tabColor(2)} /> <Text style={[{ color: tabColor(2) }, styles.labelText]}>Comunidad</Text> </View> </Pressable> {/* 个人资料tab */} <Pressable onPress={() => { setFocused(3); navigate('/perfil'); }}> <View style={styles.tab}> <Icon name="account" size={25} color={tabColor(3)} /> <Text style={[{ color: tabColor(3) }, styles.labelText]}>Perfil</Text> </View> </Pressable> {/* 设置tab */} <Pressable onPress={() => { setFocused(4); navigate('/ajustes'); }}> <View style={styles.tab}> <Icon name="cog" size={25} color={tabColor(4)} /> <Text style={[{ color: tabColor(4) }, styles.labelText]}>Ajustes</Text> </View> </Pressable> </View> ); } const { width, height } = Dimensions.get('window'); const styles = StyleSheet.create({ container: { position: 'absolute', bottom: 0, left: 0, right: 0, flexDirection: 'row', justifyContent: 'space-around', alignItems: 'center', height: height * 0.15, width: width, backgroundColor: '#303747', }, labelText: { fontSize: 15, }, tab: { alignItems: 'center', } });
关键说明
- 移除嵌套组件:用
useNavigate实现命令式跳转,在Pressable的onPress回调里同时执行状态更新与路由跳转,彻底避免事件冲突问题。 - 同步路由与状态:通过
useLocation获取当前路由路径,用useEffect监听路径变化自动更新focused值,确保用户通过返回键或其他方式跳转时,底部栏选中状态也能同步。 - 简化代码逻辑:文本颜色直接复用
tabColor函数,减少重复判断代码。
注:你代码中导入的createBottomTabNavigator未实际使用,建议统一路由方案,避免同时混用React Navigation与react-router的API,减少潜在冲突。
内容的提问来源于stack exchange,提问作者Miguel Ángel Gómez Gómez
相关产品推荐
相关产品推荐

