如何在App.js中收到通知时跳转其他页面?useNavigation不生效如何解决?
问题根因
你的代码不生效存在两个核心问题:
useNavigation仅能在导航容器(NavigationContainer)包裹的内部屏幕组件中调用,你在根组件App.js中调用时,组件不在导航上下文范围内,无法获取到有效的导航实例。- 你在普通函数
UserScreen中调用Hook,违反了React Hook只能在组件顶层、自定义Hook中调用的规则,本身执行逻辑存在错误。
解决方法
方法1:使用官方推荐的「导航引用」实现导航器外跳转
这是最适配你当前代码结构的方案,无需调整现有导航层级:
- 首先创建导航引用封装文件
navigationRef.js:
import { createNavigationContainerRef } from '@react-navigation/native'; export const navigationRef = createNavigationContainerRef(); // 封装跳转方法,自动处理导航未初始化的异常 export function navigate(name, params) { if (navigationRef.isReady()) { navigationRef.navigate(name, params); } }
- 调整App.js代码,绑定引用、替换跳转逻辑:
import { NavigationContainer } from '@react-navigation/native'; import { navigationRef, navigate } from './navigationRef'; export default function App() { useEffect(() => { const backgroundSubscription = Notifications.addNotificationResponseReceivedListener( (response) => { switch (response.request?.content.data.type) { case 'chat': navigate('Chat'); break; default: return console.log('Entro al default') } } ); const foregroundSubscription = Notifications.addNotificationReceivedListener( (notification) => { switch (notification.request?.content.data.type) { case 'chat': // 前台收到通知建议先弹窗确认再跳转,避免打断用户当前操作 navigate('Chat'); break; default: return console.log('Entro al default') } } ); return () => { backgroundSubscription.remove(); foregroundSubscription.remove(); }; }, []); return ( <Provider store={store}> {/* 给导航容器绑定刚才创建的ref,如果你把NavigationContainer封装到了SparkitNavigator内部,就把ref绑定到内部的NavigationContainer上 */} <NavigationContainer ref={navigationRef}> <SparkitNavigator /> </NavigationContainer> </Provider> ); }
方法2:将通知监听逻辑移入导航内部屏幕
如果你不想维护全局导航引用,可以把通知监听逻辑放到APP启动后的第一个首页组件里,该组件本身在导航容器内部,直接调用useNavigation即可拿到有效实例完成跳转。
内容的提问来源于stack exchange,提问作者Julio Palacios
相关产品推荐
相关产品推荐

