Reputation: 325
I used a material -ui Dialog. The dialog is not able to open and close repeatly for my lack of ability. After closing the dialog , it was no logener open again. How Should I fix my code? I am using React and Redux . function OpenPepsi is in Container. can is got from Promise object.
function MainPage(props: Material) {
return (
<React.Fragment>
<Link variant="h3" onClick={props.OpenPepsi}>
OpenPepsiDialog
</Link>
<br />
{props.can && (
<PepsiDialog
can ={props.can}
isOpen={!!props.can}
/>
)}
function PepsiDialog(props: {
c: can;
isOpen: boolean;
}) {
const [open, setOpen] = React.useState(props.isOpen);
const handleClose = () => {
setOpen(false);
};
return (
<Dialog open={open} onClose={handleClose}>
<React.Fragment>{c}</React.Fragment>
);
action
export const OPEN_PEPSI = () => async (dispatch: Dispatch) => {
const can = await getPepsi(FOO);
dispatch(OPEN_PEPSI_NOTIFY(can));
};
Upvotes: 1
Views: 3526
Reputation: 11848
This line leads to incorrect behavior
const [open, setOpen] = React.useState(props.isOpen);
Seems that you're updating props.isOpen
in parent and expect to update open
inside dialog. But this will not work. Argument of useState
is used to initialize state, but will not change it on subsequent calls of component (till it mounted). So to update open
variable based on props.isOpen
you should add useEffect
like below
useEffect (() => setOpen(props.isOpen), [props.isOpen])
This way open
will be updated based on isOpen
change.
But this sinplified form has one drawback. Dialog will be reopened only when can
in Redux change to false
and then again to true
. So maybe you want to propagate closed state back to Redux store. In such case connect PepsiDialog
to Redux and use can
directly from Redux (remove local useState
). Or alternatively you can pass callback to PepsiDialog
which will be called on close and parent MainPage
will propagate closed state to Redux
Upvotes: 1