Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Material-ui multiple snackbar

I am trying to get multiple warnings with Snackbar of the material ui, they have been unsuccessful so far, I saw some examples with Vue, but nothing with react, can someone help me? Follow my code below

https://codesandbox.io/embed/withered-sunset-ru3p3?fontsize=14&hidenavigation=1&theme=dark

like image 727
pri sil Avatar asked Apr 20 '26 01:04

pri sil


2 Answers

Material-ui does not allow multiple snackbars by default. As a matter of fact such behavior is discouraged by material design specification. Though if you really want to get it working you can use third-party libraries such as notistack that uses the very same components from material-ui.

like image 149
aleksxor Avatar answered Apr 21 '26 13:04

aleksxor


I am using react-redux to store my messages. messages, of type list; each element of contains a unique id, a message, and severity, i.e messages = [{'id': uuidv4(), 'message': 'invalid input', 'severity': 'error'}, {'id': uuidv4(), 'message': 'document updated successfully', 'severity': 'success'}] where uuidv4() import { v4 as uuidv4 } from "uuid";. I use a uuid for each message id instead of its index in the list as different messages can share the same index once one gets deleted. This approach solves the issue with <Stack /> only displaying 1 <Snackbar /> (or multiple Snackbars but overlapping on top of each other).

/// reducer
case SNACKBAR_WRITE:
  return {
    ...state,
    messages: [
      ...state.messages,
      {
        id: uuidv4(),
        message: payload.message,
        severity: payload.severity,
      },
    ],
  };
case SNACKBAR_DELETE:
  return {
    ...state,
    messages: state.messages.filter((message) => message.id !== payload),
  };

/// custom component
import React, { useEffect } from "react";
import { connect } from "react-redux";
import { remove_snackbar } from "../../actions/auth";
import { Alert } from "@mui/material";

const CustomAlert = ({ message, remove_snackbar }) => {
    useEffect(() => {
      setTimeout(function () {
          remove_snackbar(message.id);
      }, 8000);
    }, [message, remove_snackbar]);

    const handleAlertClose = (event, reason) => {
      if (reason === "clickaway") {
          return;
      }
      remove_snackbar(message.id);
    };

    return (
      <Alert
          onClose={handleAlertClose}
          elevation={6}
          variant="filled"
          severity={message.severity}
      >
          {message.message}
      </Alert>
    );
};

export default connect(null, { remove_snackbar })(CustomAlert);

///main jsx
<Stack sx={{ position: "absolute", bottom: 24, right: 24 }} spacing={2}>
   {messages.map((message) => (<CustomAlert message={message} key={message.id} />))}
</Stack>
like image 25
Youssef Kanbour Avatar answered Apr 21 '26 15:04

Youssef Kanbour



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!