使用React Hooks的函数中如何正确使用clearInterval解决弹窗不消失问题
问题排查
你写的clearInterval语法本身没有问题,弹窗无法消失的核心原因是业务逻辑存在疏漏,和定时器销毁逻辑无关,具体问题如下:
- 已触发的提醒没有做已标记处理:你过滤
activeReminders时用了!note.isReminderShow作为条件,但触发提醒后没有把对应note的isReminderShow字段改为true,导致同一个提醒会被定时器每秒反复命中,持续将showNotifyModal设为true,哪怕你手动关闭弹窗也会立刻重新弹出。 - 无符合条件的提醒时没有重置弹窗状态:
handleReminder函数只处理了找到提醒时打开弹窗的逻辑,没有匹配到符合时间的提醒时,没有主动关闭弹窗、清空当前激活提醒。 activeReminders更新逻辑有疏漏:第二个useEffect只在notesWithReminder长度大于0的时候才更新activeReminders,如果所有提醒都已触发,activeReminders不会被清空,定时器会一直基于旧的数组运行。
修复方案
你可以按如下逻辑调整代码:
useEffect(() => { const interval = setInterval(() => { handleReminder(activeReminders); }, 1000); return () => clearInterval(interval); }, [activeReminders]); useEffect(() => { const notesWithReminder = getNotesWithReminder(notes); // 不管长度是否为0都更新,保证所有提醒触发后数组被清空 setActiveReminders(notesWithReminder); }, [notes]); function getNotesWithReminder(notes) { return notes.filter((note) => note.reminder && !note.isReminderShow); } function handleReminder(reminders) { const activeRem = reminders.find((rem) => { const now = Date.now(); const getRemTime = new Date(rem.reminder).getTime(); return getRemTime <= now; }); if (activeRem) { setActiveReminder(activeRem); setShowNotifyModal(true); // 标记该提醒已触发,更新原notes数组(这里setNotes是你原有的更新notes的方法,替换成你实际的方法名即可) setNotes(prevNotes => prevNotes.map(note => { if (note.id === activeRem.id) { return {...note, isReminderShow: true} } return note })) } else { // 没有匹配到提醒时关闭弹窗 setActiveReminder(null); setShowNotifyModal(false); } }
另外你手动关闭弹窗的逻辑里,也要同步把showNotifyModal设为false,避免状态残留。
内容的提问来源于stack exchange,提问作者Barak David
相关产品推荐
相关产品推荐

