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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:57:10