Home > Software engineering >  onClick function in .map keeps being called
onClick function in .map keeps being called

Time:09-21

I have an array that I loop through using .map.For each item in the loop, there's a button with an onClick listener used as a delete button. I use Material UI's "Dialog" as a confirmation prompt. The Dialog, however, keeps getting called as soon as I add a value to the function that is called with the button.

<Button onClick={this.handleClickOpen(value)}> <-- Adding the (value) part makes it being called on all items, not just once.

class planner extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      tasks: [],
      open: false,
    };
  }

  handleClickOpen = (value) => {
    console.log(value);
    this.setState({ open: true });
  };

  dismissDialog = () => {
    this.setState({ open: false });
  };

  acceptDialog = (index) => {
    console.log("Deleted task with index: "   index);
  };

  componentDidMount = () => {
    this.handleSubmit();
  };

  handleSubmit = async () => {
    try {
      const response = await axios({
        method: "get",
        url: "http://localhost:3001/tasks",
        headers: { "Content-Type": "multipart/form-data" },
      }).then((res) => {
        this.setState({ tasks: res.data.data });
        console.log(this.state.tasks);
        return res.data.data;
      });
    } catch (error) {
      console.log(error);
    }
  };

  render() {
    return (
      <div className="Planner">
        <h1>PLANNER</h1>

        <ul>
          {this.state.tasks.map((value, index) => {
            return (
              <li key={index}>
                <Card>
                  <div className="container">
                    <div className="item">
                      <CardContent>
                        <Typography gutterBottom variant="h5" component="div">
                          {value.title}
                        </Typography>
                        <Typography variant="body2" color="text.secondary">
                          {value.discription}
                        </Typography>
                      </CardContent>
                    </div>
                    <div className="item_right">
                      <Typography gutterBottom component="div"></Typography>
                      <CardActions>
                        <Button
                          onClick={this.handleClickOpen(value)}
                        >
                          <CardMedia
                            component="img"
                            alt="Task delete icon"
                            height="25"
                            image={deleteTaskIcon}
                          />
                        </Button>
                      </CardActions>
                    </div>
                  </div>
                  <Dialog
                    open={this.state.open}
                    onClose={this.handleClose}
                    aria-labelledby="alert-dialog-title"
                    aria-describedby="alert-dialog-description"
                  >
                    <DialogTitle id="alert-dialog-title">
                      Delete task?
                    </DialogTitle>
                    <DialogContent>
                      <DialogContentText id="alert-dialog-description">
                        Are you sure you want to delete the task:
                      </DialogContentText>
                    </DialogContent>
                    <DialogActions>
                      <button onClick={this.dismissDialog}>Dismiss</button>
                      <button onClick={this.acceptDialog} autoFocus>
                        Accept
                      </button>
                    </DialogActions>
                  </Dialog>
                </Card>
              </li>
            );
          })}
        </ul>

        <Button variant="contained" href="/planner-create-item">
          Create Item
        </Button>
      </div>
    );
  }
}

export default planner;

CodePudding user response:

here <Button onClick={this.handleClickOpen(value)}> you are calling this function to the component which makes here get immediately called when the component mounts and is being called every time the component renders.

Instead, pass the function itself like this : <Button onClick={()=> this.handleClickOpen(value)}>

  • Related