React Native调用useNavigation跳转报Invalid hook call错误如何解决
错误原因
React Hook 有强制调用规则,useNavigation 作为 Hook 只能在函数组件的顶层作用域调用,你当前在FacebookLogin异步回调函数内调用useNavigation,不符合Hook调用规则,直接触发Invalid hook call报错。
修复方案
将useNavigation的调用移到LoginScreen组件顶层,拿到导航实例后再在登录逻辑中使用即可,修复后的完整代码如下:
import { useNavigation } from '@react-navigation/native'; import { StackNavigationProp } from '@react-navigation/stack'; // 路由参数类型定义,可根据你的实际路由配置调整 type RootStackParamList = { Dashboard: undefined; // 其余路由配置可在此补充 }; type AuthScreenProp = StackNavigationProp<RootStackParamList, 'Dashboard'>; export default function LoginScreen({ path }: { path: string }) { // 组件顶层调用Hook获取导航实例 const navigation = useNavigation<AuthScreenProp>(); // 登录逻辑写在组件内部,直接调用已拿到的navigation实例 async function FacebookLogin(){ try { await Facebook.initializeAsync({ appId: '...', }); const data = await Facebook.logInWithReadPermissionsAsync({ permissions: ['public_profile'], }); if (data.type === 'success') { const response = await fetch(`https://graph.facebook.com/me?access_token=${data.token}`); // 响应体仅可读取一次,先存入变量再复用 const userInfo = await response.json(); Alert.alert('Logged in!', `Hi ${userInfo.name}!`); navigation.navigate('Dashboard'); } } catch ({ message }) { alert(`Facebook Login Error: ${message}`); } } return ( <Container style={styles.container} > <FormControl> <Button style={styles.loginButton} onPress={FacebookLogin}> <Text style={styles.textButton}>Login with Facebook</Text> </Button> </FormControl> </Container> ); }
注意事项
- 所有React Hook(useState、useEffect、useNavigation等)均不可在条件判断、循环、异步函数、普通回调函数内部调用,必须保证组件每次渲染时Hook的调用顺序完全一致。
- 如果你不想把登录逻辑写在组件内部,也可以单独提取
FacebookLogin为外部函数,将navigation作为参数传入即可,核心是保证useNavigation仅在组件顶层调用。 - 原代码中
await response.json()调用了两次,fetch返回的响应体只能读取一次,修复后的代码将结果存入变量复用,避免出现响应体已被锁定的报错。
内容的提问来源于stack exchange,提问作者Anamaria Afanasov
相关产品推荐
相关产品推荐

