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

使用useNavigation实现Header路由图标激活背景色,避免双击无效问题

解决点击导航按钮需双击切换激活背景色的问题

问题原因

你的clickedButton状态应该是存储在当前页面组件内部的。当调用navigate跳转到新页面时,原页面组件会被卸载,状态随之丢失;返回时组件重新挂载,状态回到初始值,导致第一次点击仅完成导航,第二次点击才会更新激活状态,出现双击的情况。

解决方案

方案1:用全局Context管理激活状态

将激活状态提升到导航容器的上层组件,确保状态在页面切换时不会丢失:

  1. 创建导航状态Context:
// NavigationContext.js
import { createContext, useContext, useState } from 'react';

const NavigationContext = createContext();

export function NavigationProvider({ children }) {
  const [activeTab, setActiveTab] = useState('home');

  return (
    <NavigationContext.Provider value={{ activeTab, setActiveTab }}>
      {children}
    </NavigationContext.Provider>
  );
}

export function useNavigationState() {
  return useContext(NavigationContext);
}
  1. 在App.js中包裹导航容器:
// App.js
import { NavigationProvider } from './NavigationContext';
import { NavigationContainer } from '@react-navigation/native';
// 导入你的导航栈配置

export default function App() {
  return (
    <NavigationProvider>
      <NavigationContainer>
        {/* 你的导航栈/抽屉导航等 */}
      </NavigationContainer>
    </NavigationProvider>
  );
}
  1. 在Header组件中使用Context:
import { useNavigationState } from './NavigationContext';
import { useNavigation } from '@react-navigation/native';

function Header() {
  const { activeTab, setActiveTab } = useNavigationState();
  const navigation = useNavigation();

  const handleButtonClick = (tabName, routePath) => {
    setActiveTab(tabName);
    routePath && navigation.navigate(routePath);
  };

  return (
    <>
      <Button
        style={activeTab === 'home' ? { backgroundColor:'#D3D3D3' } : {}}
        color="inherit"
        onClick={() => handleButtonClick('home', '/home')}
      >
        <HomeIcon />
      </Button>

      <Button
        style={activeTab === 'btn2' ? { backgroundColor: '#D3D3D3' } : {}}
        color="inherit"
        onClick={() => handleButtonClick('btn2', '/next-page')}
      >
        <DocumentScannerIcon />
      </Button>
      {/* 其他按钮 */}
    </>
  );
}

方案2:利用当前路由自动匹配激活状态(更推荐)

直接通过useRoute获取当前路由名称,自动匹配激活状态,无需手动维护额外状态:

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

function Header() {
  const navigation = useNavigation();
  const route = useRoute();

  // 建立路由名称与tab标识的映射
  const routeTabMap = {
    'Home': 'home',
    'NextPage': 'btn2',
    // 补充其他路由与tab的对应关系
  };

  // 当前激活的tab
  const currentActiveTab = routeTabMap[route.name] || 'home';

  const handleButtonClick = (routeName) => {
    navigation.navigate(routeName);
  };

  return (
    <>
      <Button
        style={currentActiveTab === 'home' ? { backgroundColor:'#D3D3D3' } : {}}
        color="inherit"
        onClick={() => handleButtonClick('Home')}
      >
        <HomeIcon />
      </Button>

      <Button
        style={currentActiveTab === 'btn2' ? { backgroundColor: '#D3D3D3' } : {}}
        color="inherit"
        onClick={() => handleButtonClick('NextPage')}
      >
        <DocumentScannerIcon />
      </Button>
      {/* 其他按钮 */}
    </>
  );
}

这个方案完全依赖路由状态,不会出现状态不同步的问题,彻底解决双击问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 08:03:02