I’m trying to use React’s ‘notistack’ module to display several notifications as a stack. However, it appears that I am making a mistake, as Whenever I receive a warning:
react_devtools_backend.js:3973 Warning: Cannot update during an existing state transition (such as within render)
I’m using the state here to set the Response messages(they are coming from api), which are an array of notifications. Once the alerts have been rendered, I should also make the state of the Response messages an empty array.
renderPage.js
import React, { useState, useContext } from "react";
import axios from "axios";
import Button from "@mui/material/Button";
import Typography from "@mui/material/Typography";
import { SnackbarProvider } from "notistack";
import Zoom from "@material-ui/core/Slide";
import Notification from "../../components/Notification";
import { handleResponse } from "../../services/responseHandler";
import { SelectedRunnerContext } from "./RunnersPage";
export function RunnersForm() {
const { selected } = useContext(SelectedRunnerContext);
const [responseMessages, setResponseMessages] = useState([]);
const notistackRef = React.createRef();
const onClickDismiss = (key) => () => {
notistackRef.current.closeSnackbar(key);
};
const MakePostRequest = (event) => {
event.preventDefault();
setResponseMessages([]);
const data = {
selected_runners: selected,
};
const requestOptions = {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
body: data,
};
axios
.post("/messages", requestOptions)
.then((response) => {
const result = handleResponse(response.data);
setResponseMessages(result);
})
.catch((error) => {
console.log(error);
});
};
return (
<>
<Button onClick={MakePostRequest}>Post</Button>
{!!responseMessages.length && (
<SnackbarProvider
maxSnack={4}
ref={notistackRef}
dense
preventDuplicate
anchorOrigin={{
vertical: "bottom",
horizontal: "right",
}}
TransitionComponent={Zoom}
sx={{
width: 700,
}}
style={{
fontSize: 15,
fontWeight: 700,
}}
action={(key) => (
<Button onClick={onClickDismiss(key)}>
<Typography
variant="subtitle2"
style={{
fontWeight: 600,
fontSize: 16,
color: "#00579b",
}}
>
Dismiss
</Typography>
</Button>
)}
>
<Notification messages={responseMessages} />
</SnackbarProvider>
)}
</>
);
}
Notification.js
import React, { Fragment } from "react";
import { useSnackbar } from "notistack";
export default function Notification(props) {
const { enqueueSnackbar } = useSnackbar();
const { messages } = props;
const options = {
variant: "success",
autoHideDuration: 6000,
transitionDuration: { enter: 400, exit: 400 },
};
messages.forEach((msg) => {
enqueueSnackbar(msg, options);
});
return <></>;
}