How to call dialog box from another file in React

Viewed 2659

I am very new to React so this may seem a little trivial. I have a delete icon in one file which when clicked, I am trying to program a confirmation dialog box. Using the source of their website: https://material-ui.com/components/dialogs/. My file is comprises of a listview:

ListView:

import React from 'react';
import PropTypes from 'prop-types';
import { List, ListItem, ListItemText, ListItemAvatar, Avatar, ListItemSecondaryAction, IconButton } from '@material-ui/core';
import DeleteIcon from '@material-ui/icons/Delete';

import AlertDialog from './AlertDialog'

// Import CSS
import './ListViewer.css'

export function ListViewer({ objects}) {
  return (
    <div className='list-viewer'>
      <List>
        <ListItem alignItems="center" divider key={obj.id}>
            <ListItemText primary={objects.name} /> 
            <ListItemSecondaryAction>
                <IconButton edge="end" aria-label="delete" onClick={handleClickOpen()}>
                <DeleteIcon />
                </IconButton>
            </ListItemSecondaryAction>
        </ListItem>
      </List>
    </div>
  );
}

AlertDialog.js:

import React from 'react';
import Button from '@material-ui/core/Button';
import Dialog from '@material-ui/core/Dialog';
import DialogActions from '@material-ui/core/DialogActions';
import DialogContent from '@material-ui/core/DialogContent';
import DialogContentText from '@material-ui/core/DialogContentText';
import DialogTitle from '@material-ui/core/DialogTitle';

export default function AlertDialog() {
  const [open, setOpen] = React.useState(false);

  const handleClickOpen = () => {
    setOpen(true);
  };

  const handleClose = () => {
    setOpen(false);
  };

  return (
    <div>

      {/* <Button variant="outlined" color="primary" onClick={handleClickOpen}>
        Open alert dialog
      </Button> */}
      <Dialog
        open={open}
        onClose={handleClose}
        aria-labelledby="alert-dialog-title"
        aria-describedby="alert-dialog-description"
      >
        <DialogTitle id="alert-dialog-title">{"Are you sure you want to delete this object?"}</DialogTitle>
        <DialogContent>
          <DialogContentText id="alert-dialog-description">
            Deleting this object will permanently remove it 
          </DialogContentText>
        </DialogContent>
        <DialogActions>
          <Button onClick={handleClose} color="primary">
            Cancel
          </Button>
          <Button onClick={handleClose} color="primary" autoFocus>
            Delete
          </Button>
        </DialogActions>
      </Dialog>
    </div>
  );
}

As you can see in AlertDialog, there was initially a button which triggers the dialog to open. Instead from my other file, when the delete icon is clicked, I am trying to trigger the dialog. How can I do this? I have imported AlertDialog and AlertDialog.handleClickOpen but this does not work as handleClickOpen is not a function

3 Answers

You can pass open and onClose via props into AlertDialog.

function AlertDialog(props) {
  const { open, onClose } = props

  return (
    <Dialog
      open={open}
      onClose={onClose}
    >
      {/* Dialog content */}
    </Dialog>

Then, simply use it in ListView:

function ListView() {
  const [dialogIsOpen, setDialogIsOpen] = React.useState(false)

  const openDialog = () => setDialogIsOpen(true)

  const closeDialog = () => setDialogIsOpen(false)

  return (
    <div className='list-viewer'>
      <List>{/* Now you can set dialogIsOpen here */}</List>
      <AlertDialog open={dialogIsOpen} onClose={closeDialog} />
    </div>
  )
}

There are a few steps how I would do it the first is that I would do instead of a open and close function I would do one as this:

const toggleDialog = useCallback(() => {
    setOpen(!open);
  }, [open]);

The useCallback function makes it that it only creates a new function when the parameter in the [] changes, means when open changes.

Sadly @Code-Apprentice was faster and metioned the rest to it.

<IconButton edge="end" aria-label="delete" onClick={handleClickOpen()}>

The onClick handler here must be in the same class that renders the <IconButton>. Also, remove the parentheses to set the onClick prop to the function instead of its return value:

onClick={handleClickOpen}
Related