Material ui dialog closes the snackbar along with it.
This is a weird problem so I created a demo to demonstrate the issue:
https://codesandbox.io/s/react-hooks-counter-demo-v20w3
I am passing states from parent to child so the parent state can update based on the child
<Child openDialog={openDialog} setOpenDialog={setOpenDialog} />
In the child, I am using these as below
export default function Child({openDialog, setOpenDialog}) {
The button in the child is supposed to close only the dialog but it closes snackbar too.
<button
onClick={() => dialogClick()}
>Click this dialog button
</button>
Line 12 in the child has setOpenSnack("true");
This only works when I comment out line 13 setOpenDialog(false);
const dialogClick = (event) => {
setMsg("This should close dialog only and open the snackbar");
setOpenSnack(true);
setOpenDialog(false);
};
This behavior is only when I split it into child and parent.
In short, why does setOpenSnack(true);
in the child not work?
Move your Snackbar
to your parent component so that it's not dependent on Dialog
's lifecycle.
App.js
import DialogBody from "./child";
function App() {
const [openDialog, setOpenDialog] = useState(false);
const [openSnack, setOpenSnack] = useState(false);
const [msg, setMsg] = useState("nothing");
function doApiCall(formData) {
// do your API calls here
console.log(formData);
// when done hide dialog, show snackbar
setOpenDialog(false);
setOpenSnack(true);
}
const fireOnClick = (event) => {
setMsg("you clicked a button");
setOpenDialog(true);
};
const handleCloseSnack = (event, reason) => {
if (reason === "clickaway") {
return;
}
setOpenSnack(false);
};
function Alert(props) {
return <MuiAlert elevation={6} variant="filled" {...props} />;
}
return (
<div className="App">
<h3>click button below to open dialog</h3>
<button onClick={() => fireOnClick()}>Click me</button>
<Dialog open={openDialog}>
<DialogTitle>This is a dialog</DialogTitle>
<DialogBody doApiCall={doApiCall} />
</Dialog>
<Snackbar
open={openSnack}
autoHideDuration={6000}
onClose={handleCloseSnack}
>
<Alert onClose={handleCloseSnack} severity="error">
{msg}
</Alert>
</Snackbar>
</div>
);
}
Child.js
export default function DialogBody({ doApiCall }) {
const [name, setName] = React.useState("");
function onChange(event) {
setName(event.target.value);
}
return (
<div>
<input type="text" value={name} onChange={onChange} />
<button onClick={() => doApiCall({ name })}>
Click this dialog button
</button>
</div>
);
}
Our DialogBody
component only accepts a prop called doApiCall
from our parent, which is invoked by clicking the Click this dialog button
.
doApiCall
might be an asynchronous call to your backends API which when resolves will hide the dialog and sets the snackbar to open.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With