React Native中Alert自动触发两次问题(Expo SDK39环境)
解决Expo SDK39中推送通知Alert重复触发的问题
我来帮你拆解下你遇到的这个问题:在Expo SDK39的React Native项目里,处理推送通知时Alert.alert()会自动弹两次,但只保留console.warn()时看起来没有重复触发——其实后者也执行了两次,只是控制台输出没那么显眼,而弹窗的视觉反馈让重复问题更突出。
核心原因分析
最常见的触发点有两个:
- 监听器重复注册:如果你的组件被多次挂载(比如导航切换、页面重新渲染),
componentDidMount会重复执行,导致多个通知监听器同时存在。每收到一条通知,所有活跃的监听器都会触发一次_handleNotification,自然就弹出两次Alert。 - 通知重复回调:Expo在SDK39中,对于前台通知、后台唤醒通知的处理逻辑可能存在重叠,同一个通知会被回调两次;或者通知本身的payload里存在重复标识,导致被重复处理。
具体解决方案
1. 及时清理监听器,避免重复注册
在组件卸载时移除通知订阅,确保每次组件挂载时只有一个监听器生效:
componentDidMount(){ this._notificationSubscription = Expo.Notifications.addListener( this._handleNotification ); } // 新增组件卸载时的清理逻辑 componentWillUnmount() { if (this._notificationSubscription) { this._notificationSubscription.remove(); } }
2. 给通知做去重处理
通过通知的唯一标识(比如requestId)记录已处理的通知,避免重复触发Alert:
constructor(props) { super(props); // 用Set存储已处理的通知ID,确保每个通知只处理一次 this.processedNotifications = new Set(); } _handleNotification(notification){ // 先判断是否已经处理过这个通知 if (this.processedNotifications.has(notification.requestId)) { return; } this.processedNotifications.add(notification.requestId); if (notification.data) { console.warn('inside if block') Alert.alert( "push notification", // 这里建议补充通知内容,原代码漏了Alert的第二个消息参数 notification.data.content || "您收到一条新通知", [ { text: "Cancel" }, { text: "Ok", onPress: () => this.props.navigation.navigate("More") }, ], { cancelable: false } ); } }
3. 区分通知的触发场景(可选)
你也可以通过notification.origin判断通知的来源,只处理特定场景的通知:
_handleNotification(notification){ // 只处理前台收到的通知,避免后台唤醒时的重复回调 if (notification.origin !== 'received') { return; } // 后续的去重和Alert逻辑... }
4. 考虑升级Expo SDK(可选)
Expo SDK39存在一些已知的推送通知相关bug,升级到SDK40及以上版本可以修复部分重复回调的问题。不过升级前记得做好依赖兼容性测试,避免引入新问题。
内容的提问来源于stack exchange,提问作者Binit Chandra Jha
相关产品推荐
相关产品推荐

