You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中使用notistack页面跳转时如何正确处理Snackbar?

问题分析

当前Snackbar返回页面后短暂显示即关闭的核心问题在于:

  1. 两个独立useEffect共享同一个挂载状态判断,逻辑混乱,卸载时两次调用无参closeSnackbar()(会关闭所有Snackbar),引发状态冲突;
  2. 返回页面时,若数据从缓存获取,挂载判断逻辑导致Snackbar触发时机异常,加上无差别关闭操作,导致刚打开就被关闭。
解决方案

通过合并逻辑、精准控制Snackbar生命周期来修复问题,修改后的ProfilePageStatistics组件代码如下:

import { useEffect, useRef } from 'react';
import { useSnackbar } from 'notistack';

export default function ProfilePageStatistics() {
  const { data } = userGetStatistics(); // 数据请求Hook
  const { enqueueSnackbar, closeSnackbar } = useSnackbar();
  const snackbarKeys = useRef({ expiring: null, expired: null });
  const isFirstMount = useRef(true);

  const messages = {
    expiring: 'Less than 15 days remaining',
    expired: 'Expired',
  };

  useEffect(() => {
    // 首次挂载时跳过,等待数据加载完成
    if (isFirstMount.current) {
      isFirstMount.current = false;
      return;
    }

    // 先关闭之前打开的对应Snackbar,避免重复堆积
    if (snackbarKeys.current.expiring) {
      closeSnackbar(snackbarKeys.current.expiring);
      snackbarKeys.current.expiring = null;
    }
    if (snackbarKeys.current.expired) {
      closeSnackbar(snackbarKeys.current.expired);
      snackbarKeys.current.expired = null;
    }

    // 显示需要的Snackbar并保存唯一key
    if (data?.count15Days) {
      snackbarKeys.current.expiring = enqueueSnackbar(messages.expiring, {
        variant: 'certificateStatus',
        persist: true,
      });
    }
    if (data?.countExpired) {
      snackbarKeys.current.expired = enqueueSnackbar(messages.expired, {
        variant: 'certificateStatus',
        persist: true,
      });
    }

    // 组件卸载时仅关闭当前组件打开的Snackbar
    return () => {
      if (snackbarKeys.current.expiring) {
        closeSnackbar(snackbarKeys.current.expiring);
      }
      if (snackbarKeys.current.expired) {
        closeSnackbar(snackbarKeys.current.expired);
      }
    };
  }, [data, enqueueSnackbar, closeSnackbar]);

  return <div>Profile Statistics Content</div>;
}
关键修改点说明
  1. 合并useEffect逻辑:将两个独立的Snackbar处理逻辑合并为一个,监听完整的data对象,避免拆分依赖导致的逻辑冲突;
  2. 精准控制Snackbar关闭:用snackbarKeys保存每个Snackbar的唯一key,卸载时仅关闭当前组件打开的Snackbar,不会影响其他页面的Snackbar;
  3. 调整挂载判断逻辑:isFirstMount确保首次挂载(包括返回页面的重新挂载)时,等待数据加载完成后再触发Snackbar显示;
  4. 避免重复显示:每次数据更新时先关闭之前的对应Snackbar,防止同一提示重复堆积。
注意事项
  • 确保userGetStatistics返回的data在组件重新挂载时能正确更新(若使用缓存,需保证返回最新状态);
  • 若userGetStatistics是异步请求,首次挂载时data会从undefined变为有值,此时useEffect会自动触发,正确显示Snackbar。

内容的提问来源于stack exchange,提问作者Beibit Temirzhanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 03:14:58