Search code examples
reactjstypesmaterial-uidialogparent-child

Unable to open MUI Dialog from parent component in React


I am using React Typescript and MUI. I have a parent component with an 'Edit' button, when clicked , should display Dialog box with a form pre-populated with that specific data from the parents.Can use static data for the parent now, to display on the Dialog form. I am unable to open the Dialog from the parent component. Parents.tsx

interface Post {    
    id: number;
    name: string;
    email: string; 
  }
  
  export default function Parents()  {
    const [open, setOpen] = React.useState(false);
    const [posts, setPosts] = useState<Post | null>(null);
    const [error, setError] = useState<string | null>(null);

    const handleClickOpen = () => {
        setOpen(true);
      };
    
      const handleClose = () => {
        setOpen(false);
      };
  
  
  
    return (
      <React.Fragment>
      <div>
        <h1>Profile</h1>
        {error && <div>Error: {error}</div>} 
        {posts && (
        <div>                 
          <p>Name: {posts.name}</p>
          <Divider/>
          <p>Email: {posts.email}</p>
        </div>
      )}
     
      <button   onClick={handleClickOpen}>Edit</button> 
      <DialogBox/>
      </div>
      </React.Fragment>
    );

  };

Dialog.tsx

export default function DialogBox(){
    const [open, setOpen] = React.useState(false);
 
    const handleClickOpen = () => {
        setOpen(true);
      };
    
      const handleClose = () => {
        setOpen(false);
      };

      
    return (
        <React.Fragment>        
        <Dialog
          open={open}
          onClose={handleClose}
          PaperProps={{
            component: 'form',
            onSubmit: (event: React.FormEvent<HTMLFormElement>) => {
              event.preventDefault();
              const formData = new FormData(event.currentTarget);
              const formJson = Object.fromEntries((formData as any).entries());
              const email = formJson.email;
              console.log(email);
              handleClose();
            },
          }}
        >
          <DialogTitle>Edit</DialogTitle>
          <DialogContent>
            <DialogContentText>
             Edit Email address
            </DialogContentText>
            <TextField
              autoFocus
              required
              margin="dense"
              id="name"
              name="email"
              label="Email Address"
              type="email"
              fullWidth
              variant="standard"
            />
          </DialogContent>
          <DialogActions>
          <Button type="submit">Edit</Button>
            <Button onClick={handleClose}>Cancel</Button>
            
          </DialogActions>
        </Dialog>        
        </React.Fragment>
      );
}

Solution

  • To resume, you need to retrieve the "isOpen" parameter from the parent component.

    To achieve this in React you have to use props. Have a look at the documentation

    In your case, you can achieve this like so :

    <DialogBox
       isOpen={open}
    />
    

    Finally in your Dialog component, use the isOpen props passed from the parent component:

    export default function DialogBox(props){
    // const [open, setOpen] = React.useState(false);
    
    ...
    
      
    return (
        <React.Fragment>        
        <Dialog
          open={props.isOpen}
          ...
        >