如何实现通知提示按队列依次显示而不是同时弹出?

端木怡然 阅读 2

我在用 React 做一个通知系统,希望每次只显示一个提示,等当前通知关闭后再显示下一个。但现在一连触发多个操作,所有通知会同时弹出来,体验很乱。

我试过用 useState 存一个队列,然后在 useEffect 里监听队列变化去显示第一个,但关掉通知后下一个不会自动弹出,感觉状态没更新对。下面是我现在的简化代码:

const [queue, setQueue] = useState([]);
const [currentNotice, setCurrentNotice] = useState(null);

useEffect(() => {
  if (queue.length > 0 && !currentNotice) {
    setCurrentNotice(queue[0]);
    setQueue(prev => prev.slice(1));
  }
}, [queue, currentNotice]);

const showNotice = (msg) => {
  setQueue(prev => [...prev, msg]);
};

// 关闭时调用
const handleClose = () => {
  setCurrentNotice(null);
};

问题是关掉第一个后,第二个不会自动显示,得再触发一次 showNotice 才行。是不是 useEffect 的依赖或者状态更新逻辑有问题?

我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
百里润兴
问题出在你把队列里的内容提前移出来了。当你显示第一个通知时,queue 已经被 slice(1) 清空了,所以关闭后 queue.length = 0,useEffect 不会触发。

正确的做法是:显示通知时不要从队列移除,等真正关闭时再移除。改一下代码:

const [queue, setQueue] = useState([]);
const [currentNotice, setCurrentNotice] = useState(null);

useEffect(() => {
if (queue.length > 0 && !currentNotice) {
// 只取出第一个,不删除,等关闭时再删
setCurrentNotice(queue[0]);
}
}, [queue, currentNotice]);

const showNotice = (msg) => {
setQueue(prev => [...prev, msg]);
};

const handleClose = () => {
setCurrentNotice(null);
// 关闭后从队列移除第一个,useEffect 会自动检测到 queue 变化并显示下一个
setQueue(prev => prev.slice(1));
};


这样关闭时会触发两次状态更新:先设 currentNotice 为 null,queue 少一个元素,然后 useEffect 检测到 queue 还有内容且 currentNotice 为空,自动显示下一个。性能上没有任何问题,React 的状态更新是异步的,会批量处理。
点赞
2026-03-14 13:04