How to know from which DOM click event is triggered

Viewed 121

I have few Card component from material UI, each of them contain an EDIT button and there is a handler available for it, they are being added dynamically using Map traversing (In example, i have just hard coded two of them).

Now, i am trying to make the card editable in button click but not able to find out how to get to know from which Card, event is triggered and then make "Typography" of that editable to 'TextField'.

 <CardContent>
    <Typography>ID: '1'</Typography>
    <Typography
      className={classes.title}
      color="textSecondary"
      gutterBottom
    >
      Word of the Day
    </Typography>
    <Typography>Name: 'RAAM'</Typography>
    <Typography>Blood group: 'AB+'</Typography>
    <Typography>"Patient Ram is having bloodgroup AB+"</Typography>
  </CardContent>
  <CardActions>
    <Button size="small" onClick={click}>
      Edit
    </Button>
  </CardActions>
  <CardContent>

Here is my codeSandbox example CodeSandbox

2 Answers

The usual solution is to have the card pass back some identifying information or an object that you've passed it, since there's very little you can do with the React element.

If you want the DOM element, it's the currentTarget property of the event object that your click function receives.

Here's a simple example showing both with stand-ins for Card and its parent, in this case the Card component returns the id you pass it as a second argument to the click function:

"use strict";

const cards = Array.from(Array(5), (_, index) => ({
    id: index + 1,
    value: `Card ${index + 1}`
}));

function Parent() {
    const click = (evt, id) => {
        console.log(`evt.currentTarget.tagName = ${evt.currentTarget.tagName}, id = ${id}`);
    };
    return cards.map(({id, value}) =>
        <Card
          key={id}
          value={value}
          onClick={evt => click(evt, id)}
        />
    );
}

function Card({value, onClick}) {
    return <div onClick={onClick}>{value}</div>;
}

ReactDOM.render(<Parent />, document.getElementById("root"));
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js"></script>

import React, { useRef } from "react";
import { makeStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardActions from "@material-ui/core/CardActions";
import CardContent from "@material-ui/core/CardContent";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";

const useStyles = makeStyles({
  root: {
    minWidth: 275
  },
  bullet: {
    display: "inline-block",
    margin: "0 2px",
    transform: "scale(0.8)"
  },
  title: {
    fontSize: 14
  },
  pos: {
    marginBottom: 12
  }
});

export default function OutlinedCard() {
  const refs = useRef([]);
  const classes = useStyles();
  
  const click = (event) => {
    const { currentTarget: { id = "" } = {} } = event;
    const clickedCard = refs.current[id]; // This is the card whose button got clicked
    console.log(clickedCard);
  };

  const createRefs = (id, node) => (refs.current[id] = node);

  return (
    <Card className={classes.root} variant="outlined">
      <CardContent ref={(node) => {createRefs('card_1', node)}}>
        <Typography>ID: '1'</Typography>
        <Typography
          className={classes.title}
          color="textSecondary"
          gutterBottom
        >
          Word of the Day
        </Typography>
        <Typography>Name: 'RAAM'</Typography>
        <Typography>Blood group: 'AB+'</Typography>
        <Typography>"Patient Ram is having bloodgroup AB+"</Typography>
      </CardContent>
      <CardActions>
        <Button size="small" id="card_1" onClick={click}>
          Edit
        </Button>
      </CardActions>
      <CardContent ref={(node) => {createRefs('card_2', node)}}>
        <Typography>ID: '2'</Typography>
        <Typography
          className={classes.title}
          color="textSecondary"
          gutterBottom
        >
          Word of the Day
        </Typography>
        <Typography>Name: 'RAAM'</Typography>
        <Typography>Blood group: 'AB+'</Typography>
        <Typography>"Patient Ram is having bloodgroup AB+"</Typography>
      </CardContent>
      <CardActions>
        <Button size="small" id="card_2" onClick={click}>
          Edit
        </Button>
      </CardActions>
    </Card>
  );
}
Related