React Native Expo中App.js使用useNavigation的Hook调用错误问题
问题定位与解决方法
核心错误原因
你触发的「Invalid hook call」错误,本质是违反了Hook的使用规则:useNavigation必须在函数组件的顶层作用域调用,不能嵌套在回调函数、条件判断里,也不能在类组件中使用。结合你登出成功但无法跳转的情况,大概率是把useNavigation放在了Header按钮的回调逻辑里,或者没有在正确的组件层级声明。
具体修复步骤
确保Home组件是函数组件,且在顶层声明navigation
如果你是在Home组件内部处理登出,要把useNavigation放在组件最外层:import { useNavigation } from '@react-navigation/native'; import firebase from './firebase'; const Home = () => { // 必须在组件顶层声明,不能放在onPress或其他嵌套函数里 const navigation = useNavigation(); const handleLogout = async () => { try { await firebase.auth().signOut(); console.log('Signed Out Successfully'); // 登出成功后跳转 navigation.navigate('Login'); } catch (error) { console.error('Logout error:', error); } }; return ( // 你的Home页面内容 <View> {/* 如果是页面内的登出按钮,直接绑定handleLogout */} <Button title="Logout" onPress={handleLogout} /> </View> ); };如果是Header右上角的按钮,抽成独立组件
若你是在导航配置的screenOptions里定义Header按钮,不能直接在headerRight的回调中使用useNavigation,要把按钮封装成单独的函数组件:// 单独的LogoutHeaderButton组件 const LogoutHeaderButton = () => { const navigation = useNavigation(); const handleLogout = async () => { await firebase.auth().signOut(); console.log('Signed Out Successfully'); navigation.navigate('Login'); }; return <Button title="Logout" onPress={handleLogout} />; }; // 导航配置中使用 <Stack.Navigator> <Stack.Screen name="Home" component={Home} options={{ headerRight: () => <LogoutHeaderButton /> }} /> {/* 其他页面 */} </Stack.Navigator>排查依赖一致性
执行npm ls react检查项目中是否存在多份React依赖,若有重复,删除node_modules和package-lock.json后重新安装;同时确保react和react-native的版本兼容。
额外注意点
- 登出逻辑要放在
async/await里确保异步操作完成后再跳转,避免因登出未完成导致的跳转异常。 - 确认导航栈中存在名为
Login的路由,否则navigation.navigate会失效。
内容的提问来源于stack exchange,提问作者L.Calvin
相关产品推荐
相关产品推荐

