使用useNavigation实现Header路由图标激活背景色,避免双击无效问题
解决点击导航按钮需双击切换激活背景色的问题
问题原因
你的clickedButton状态应该是存储在当前页面组件内部的。当调用navigate跳转到新页面时,原页面组件会被卸载,状态随之丢失;返回时组件重新挂载,状态回到初始值,导致第一次点击仅完成导航,第二次点击才会更新激活状态,出现双击的情况。
解决方案
方案1:用全局Context管理激活状态
将激活状态提升到导航容器的上层组件,确保状态在页面切换时不会丢失:
- 创建导航状态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); }
- 在App.js中包裹导航容器:
// App.js import { NavigationProvider } from './NavigationContext'; import { NavigationContainer } from '@react-navigation/native'; // 导入你的导航栈配置 export default function App() { return ( <NavigationProvider> <NavigationContainer> {/* 你的导航栈/抽屉导航等 */} </NavigationContainer> </NavigationProvider> ); }
- 在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
相关产品推荐
相关产品推荐

