React Native调用checkNetworkConnectivity触发无效Hook调用错误求助
解决React Native中"Invalid hook call"错误的方案
错误原因
你遇到的"Error: Invalid hook call. Hooks can only be called inside of the body of a function component."错误,核心原因是**useEffect作为React Hook,只能在函数组件的顶层作用域或自定义Hook(命名必须以use开头)中调用**,而你把它写在了普通函数checkNetworkConnectivity里,并且在Navigation.events().registerAppLaunchedListener这个非组件环境中直接调用该函数,完全违反了Hook的使用规则。
正确实现方式
方案一:使用普通函数注册网络监听(适合全局启动时监听)
既然你是在App启动时就需要监听网络状态,完全不需要用Hook,直接用NetInfo的原生事件订阅API即可:
// 修改checkNetworkConnectivity为普通函数 const checkNetworkConnectivity = () => { // 注册网络状态监听 const unsubscribe = NetInfo.addEventListener((state) => { console.log('当前网络状态:', state); // 无网络时弹出警告 if (!state.isConnected) { Alert.alert('网络提示', '当前无网络连接,请检查Wi-Fi或移动数据设置'); } }); // 可选:如果需要在App退出时取消监听,可以保存unsubscribe引用,在合适时机调用 // 例如可以将unsubscribe挂载到全局对象,后续在退出逻辑中执行 // global.networkUnsubscribe = unsubscribe; }; // 保持原有调用逻辑 Navigation.events().registerAppLaunchedListener(() => { checkNetworkConnectivity(); startApp(); });
方案二:封装为自定义Hook(适合在组件中使用)
如果你希望在组件内部监听网络状态,可以将逻辑封装为符合规则的自定义Hook(命名以use开头),然后在函数组件中调用:
// 自定义网络监听Hook const useNetworkConnectivity = () => { React.useEffect(() => { const unsubscribe = NetInfo.addEventListener((state) => { console.log('当前网络状态:', state); if (!state.isConnected) { Alert.alert('网络提示', '当前无网络连接,请检查Wi-Fi或移动数据设置'); } }); // 组件卸载时取消监听 return unsubscribe; }, []); }; // 创建全局Provider组件确保只订阅一次 const AppProvider = ({ children }) => { useNetworkConnectivity(); return children; }; // 修改屏幕注册逻辑,加入AppProvider appScreens.forEach((ScreenComponent, key) => { Navigation.registerComponent( key, () => props => ( <SafeAreaProvider> <AppProvider> <ApolloProvider client={client}> <Provider store={store}> <ActionSheetProvider> <PaperProvider theme={theme}> <ScreenComponent {...props} style={{backgroundColor: 'white'}} /> </PaperProvider> </ActionSheetProvider> </Provider> </ApolloProvider> </AppProvider> </SafeAreaProvider> ), () => ScreenComponent, ); });
关键注意事项
- 所有React Hook(
useEffect、useState等)必须直接在函数组件的顶层调用,不能嵌套在普通函数、条件语句或循环中。 - 自定义Hook必须以
use开头,这样React才能识别它并应用Hook的规则。 - 如果是全局范围的事件监听(如App启动时的网络监听),优先用原生API的订阅/取消订阅逻辑,无需依赖Hook。
内容的提问来源于stack exchange,提问作者user3431310
相关产品推荐
相关产品推荐

