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

如何用React和Material UI创建通用连续Snackbars组件?

实现可复用的连续Snackbar通用组件(React 18 + MUI v5)

核心思路

通过React Context管理Snackbar队列,封装通用的Provider和自定义Hook,让应用内任意组件都能便捷触发连续Snackbar,无需重复编写队列逻辑。


1. 创建Snackbar上下文与Hook

新建SnackbarContext.jsx文件:

import { createContext, useContext, useState, useCallback } from 'react';
import { Snackbar, Alert } from '@mui/material';

const SnackbarContext = createContext();

export function SnackbarProvider({ children }) {
  const [snackbarQueue, setSnackbarQueue] = useState([]);

  // 关闭当前Snackbar,自动展示队列下一条
  const handleClose = useCallback((event, reason) => {
    if (reason === 'clickaway') return;
    setSnackbarQueue(prev => prev.slice(1));
  }, []);

  // 添加新提示到队列
  const enqueueSnackbar = useCallback((message, options = {}) => {
    setSnackbarQueue(prev => [...prev, {
      id: Date.now(),
      message,
      severity: options.severity || 'info',
      autoHideDuration: options.autoHideDuration || 6000,
      ...options
    }]);
  }, []);

  return (
    <SnackbarContext.Provider value={{ enqueueSnackbar }}>
      {children}
      {/* 仅渲染队列首项,关闭后自动切换下一条 */}
      {snackbarQueue.length > 0 && (
        <Snackbar
          key={snackbarQueue[0].id}
          open={true}
          autoHideDuration={snackbarQueue[0].autoHideDuration}
          onClose={handleClose}
          anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
        >
          <Alert
            severity={snackbarQueue[0].severity}
            onClose={handleClose}
            variant="filled"
            sx={{ width: '100%' }}
          >
            {snackbarQueue[0].message}
          </Alert>
        </Snackbar>
      )}
    </SnackbarContext.Provider>
  );
}

// 自定义Hook,简化组件调用
export function useSnackbar() {
  const context = useContext(SnackbarContext);
  if (!context) {
    throw new Error('useSnackbar必须在SnackbarProvider内部使用');
  }
  return context;
}

2. 在应用根组件注入Provider

修改App.jsx(或你的根组件文件):

import { SnackbarProvider } from './SnackbarContext';
import MainContent from './MainContent';

function App() {
  return (
    <SnackbarProvider>
      <MainContent />
    </SnackbarProvider>
  );
}

export default App;

3. 在任意组件中复用调用

在需要触发提示的组件中,直接调用自定义Hook:

import { Button, Box } from '@mui/material';
import { useSnackbar } from './SnackbarContext';

function DemoComponent() {
  const { enqueueSnackbar } = useSnackbar();

  const triggerMultipleSnackbars = () => {
    enqueueSnackbar('操作执行成功', { severity: 'success' });
    enqueueSnackbar('请注意数据格式规范', { severity: 'warning', autoHideDuration: 8000 });
    enqueueSnackbar('请求失败,请稍后重试', { severity: 'error' });
  };

  return (
    <Box sx={{ p: 2 }}>
      <Button variant="contained" onClick={triggerMultipleSnackbars}>
        触发多条提示
      </Button>
    </Box>
  );
}

export default DemoComponent;

关键说明

  • 队列机制:新提示加入队列后仅渲染首项,关闭后自动切换下一条,实现连续展示
  • 可扩展性:支持自定义提示类型、自动关闭时长等MUI原生属性
  • 全局复用:通过Context实现状态共享,任意组件无需重复编写队列逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 04:39:34