2

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 3

1

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>
  )
}
Sign up to request clarification or add additional context in comments.

7 Comments

don't do arrow functions when not needed. since it does more rendercycles. use callbacks, since it does not generate every time the function gets called a new one, when the state is the same.
@Makusium Can you elaborate on this claim? How do arrow functions generate a new function when they are called?
@Makusium Maybe you are thinking when arrow functions are written inline in the props such as open={() => setDialogOpen(true)}? I can see how this creates a new function during the render, but not when the callback is called.
@Code-Apprentice sure I can. So let's image someone presses the Open button more than once. What will happen? The there will be several functions generated when the openfunction is called. With useCallback and the parameter it will only generate the function new when open changes. Means everytime a callback function is called it refers to the old function instead of creating a new one. Also the open and the close function will be freshly generated all the structure, yes In this example it's not that bad but image if the function would be bigger.
@Code-Apprentice I made an maze game and did the same like you did without callback. I could generate 100*100 Fields and search for the cheese (BFS) with callback I was able to make without any problems 1000*1000 Field.
|
1

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.

Comments

-1
<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}

4 Comments

But the handler of this is in AlertDialog.. so how will modifying the call work
What I'm saying is the handler needs to be in ListViewer instead. You cannot modify the call to make it work they way you have it.
Right.. but AlertDialog also uses the same handler, so how can I have it work in both places?
@Nouman As other's have shown, you can pass the handler to AlertDialog as a prop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.