react-native-popup-dialog页面跳转后无法自动关闭问题求助
问题解决方案
根因分析
- 你写的
componentDidUnmount不是React官方支持的生命周期,该方法完全不会被触发 - 页面跳转使用了
NavigationService.reset逻辑,组件卸载过程中调用setState属于无效操作:此时组件即将被销毁,state更新不会触发重渲染,自然无法修改弹窗显隐状态 react-native-popup-dialog默认通过Portal机制把弹窗挂载到应用根节点,不和当前页面组件绑定渲染,所以当前页面卸载后,弹窗元素还会留在根节点上,导致跨页面显示的问题
修复步骤
1. 新增弹窗ref绑定和统一关闭逻辑
不用完全依赖state控制显隐,直接调用弹窗实例自带的dismiss方法关闭,优先级更高:
import Dialog, { DialogFooter, DialogButton, DialogContent, DialogTitle, } from 'react-native-popup-dialog'; constructor(props) { super(props); this.state = { controlDialog: false, }; // 新增弹窗ref绑定 this.dialogRef = React.createRef(); }
2. 修正生命周期和事件监听逻辑
补全事件监听的卸载逻辑,同时监听页面失焦和tab点击两个场景,触发时直接关闭弹窗:
componentDidMount() { // 监听页面失焦 this._unsubscribeBlur = this.props.navigation.addListener('blur', () => { this.closeDialog(); }); // 监听tab点击事件 this._unsubscribeTabPress = this.props.navigation.addListener('tabPress', () => { if (!this.props.navigation.isFocused()) { this.closeDialog(); } }); } componentWillUnmount() { // 卸载前主动关闭弹窗 this.closeDialog(); // 移除事件监听避免内存泄漏 this._unsubscribeBlur?.(); this._unsubscribeTabPress?.(); } // 统一封装弹窗关闭逻辑 closeDialog = () => { // 直接调用实例方法关闭弹窗 this.dialogRef.current?.dismiss(); // 同步更新state保持状态一致 this.setState({ controlDialog: false }); }
3. 给弹窗组件绑定ref
<Dialog ref={this.dialogRef} visible={this.state.controlDialog} width={0.8} // 如果修改后仍有状态不同步的问题,添加下面这行关闭原生驱动 // useNativeDriver={false} footer={ <DialogFooter style={{ paddingVertical: 10 }}> <DialogButton textStyle={{ fontSize: 16, fontWeight: "normal", color: "white", }} text="Later" onPress={this.closeDialog} /> <DialogButton textStyle={{ fontSize: 16, fontWeight: "normal", color: "white", }} text="OK" onPress={() => { // 原有OK逻辑写完后调用关闭方法即可 this.closeDialog(); }} /> </DialogFooter> } > <DialogContent></DialogContent> </Dialog>
内容的提问来源于stack exchange,提问作者tryingtofix
相关产品推荐
相关产品推荐

