user2006734
user2006734

Reputation: 325

State to open and close a Dialog in TypeScript in React

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

Answers (1)

Fyodor Yemelyanenko
Fyodor Yemelyanenko

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

Related Questions