admin管理员组

文章数量:1333210

I am calling an API to do few actions.
I want to take the response of each action and show it inside Snackbar/alert.

I am able to show only the first response and nothing else even after iterating the messages in a map.

Here is my business logic calling the api

try {
      const deletedUser = await deleteUser({ username: username });
      [deletedUser.data.status.action1, deletedUser.data.status.action2].map(
        (msg) =>
          setNotify({
            isOpen: true,
            message: msg,
            type: "success",
          })
      );
    } catch (error) {}

setNotify will open the Snackbar with the alerts

import React from "react";
import { Snackbar, Alert } from "@mui/material";

import { styled } from "@mui/material/styles";

const StyledSnackbar = styled((props) => <Snackbar {...props} />)(
  ({ theme }) => ({
    "& .MuiSnackbar-root": {
      top: theme.spacing(15),
    },
  })
);

export default function Notification(props) {
  const { notify, setNotify } = props;
  const handleClose = (event, reason) => {
    setNotify({
      ...notify,
      isOpen: false,
    });
  };
  return (
    <StyledSnackbar
      open={notify.isOpen}
      autoHideDuration={10000}
      anchorOrigin={{ vertical: "top", horizontal: "right" }}
      onClose={handleClose}
    >
      <Alert severity={notify.type} onClose={handleClose}>
        {notify.message}
      </Alert>
    </StyledSnackbar>
  );
}

The only issue it's only displaying the first action and nothing else.

Edit On Sandbox

I suspect the alerts are overlapping on top of each other Maybe we need to add some sort of AutoGrow prop

I am calling an API to do few actions.
I want to take the response of each action and show it inside Snackbar/alert.

I am able to show only the first response and nothing else even after iterating the messages in a map.

Here is my business logic calling the api

try {
      const deletedUser = await deleteUser({ username: username });
      [deletedUser.data.status.action1, deletedUser.data.status.action2].map(
        (msg) =>
          setNotify({
            isOpen: true,
            message: msg,
            type: "success",
          })
      );
    } catch (error) {}

setNotify will open the Snackbar with the alerts

import React from "react";
import { Snackbar, Alert } from "@mui/material";

import { styled } from "@mui/material/styles";

const StyledSnackbar = styled((props) => <Snackbar {...props} />)(
  ({ theme }) => ({
    "& .MuiSnackbar-root": {
      top: theme.spacing(15),
    },
  })
);

export default function Notification(props) {
  const { notify, setNotify } = props;
  const handleClose = (event, reason) => {
    setNotify({
      ...notify,
      isOpen: false,
    });
  };
  return (
    <StyledSnackbar
      open={notify.isOpen}
      autoHideDuration={10000}
      anchorOrigin={{ vertical: "top", horizontal: "right" }}
      onClose={handleClose}
    >
      <Alert severity={notify.type} onClose={handleClose}>
        {notify.message}
      </Alert>
    </StyledSnackbar>
  );
}

The only issue it's only displaying the first action and nothing else.

Edit On Sandbox

I suspect the alerts are overlapping on top of each other Maybe we need to add some sort of AutoGrow prop

Share Improve this question edited Dec 13, 2021 at 19:20 Moe asked Dec 13, 2021 at 1:02 MoeMoe 1,5375 gold badges38 silver badges59 bronze badges 5
  • Think you could create a running codesandbox that reproduces the issue for us to inspect and debug live? – Drew Reese Commented Dec 13, 2021 at 6:18
  • added a link, let me know if there is a better way of adding sandbox code to here. – Moe Commented Dec 13, 2021 at 15:22
  • codesandbox is empty. – hotcakedev Commented Dec 13, 2021 at 17:27
  • The linked codesandbox has a Notification.jsx file but it's empty. It's mostly all just the default React CSB. – Drew Reese Commented Dec 13, 2021 at 17:31
  • sorry about that, even after I forked it, I had to save manually to push the updates. The link has been updated. – Moe Commented Dec 13, 2021 at 18:35
Add a ment  | 

1 Answer 1

Reset to default 7

You have to use notistack as described in the MUI doc:

This example demonstrates how to use notistack. notistack has an imperative API that makes it easy to display snackbars, without having to handle their open/close state. It also enables you to stack them on top of one another (although this is discouraged by the Material Design guidelines).

Start by wrapping your app inside a SnackbarProvider ponent then use useSnackbar hook to access enqueueSnackbar in order to add a snackbar to the queue to be displayed:

App.js

import "./styles.css";
import React from "react";
import { SnackbarProvider } from "notistack";
import Notification from "./Notification";

export default function App() {
  return (
    <SnackbarProvider maxSnack={3}>
      <div className="App">
        <h1>Dynamic Snackbar Alerts</h1>
        <Notification />
      </div>
    </SnackbarProvider>
  );
}

Notification.js

import React from "react";
import { Button } from "@mui/material";
import { useSnackbar } from "notistack";

export default function Notification(props) {
  const { enqueueSnackbar } = useSnackbar();

  const handleClick = async () => {
    try {
      const deletedUser = await deleteUser({ username: username });
      [deletedUser.data.status.action1, deletedUser.data.status.action2].forEach((msg) => {
          enqueueSnackbar(msg, {
            variant: "success",
            autoHideDuration: 10000,
            anchorOrigin: { vertical: "top", horizontal: "right" }
          });
      });
    } catch (error) {}
  };

  return (
    <Button variant="outlined" onClick={handleClick}>
      Generate Snackbar Dynamicly
    </Button>
  );
}

Demo:

本文标签: javascriptHow to dynamically create multiple alerts inside mui v5 SnackbarStack Overflow