React拾取子节点中的onClick处理程序

时间:2019-07-31 18:59:29

标签: reactjs onclick event-handling material-ui dom-events

我正在尝试向四象限图表添加交互性,以便用户可以单击一个框以突出显示该框,而其他框将停用,这类似于单选框在表单中的工作方式。

这个想法是在每张卡上添加一个onClick事件,并具有一个处理程序功能,该功能将检查单击了哪个框,将其激活,然后将其余的框停用。

我遇到的问题是e.target似乎正在拾取每个卡的子节点,而不是卡本身,因此我很难确定单击了哪个卡。

e.g. console log = '>> event.target <li>A</li>'

我希望通过进行诸如event.target.id之类的事情来确定选择了哪张卡

我尝试了很多事情,但没有任何效果……人们通常如何设置这种类型的互动?

import React from "react";
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import CardActionArea from '@material-ui/core/CardActionArea';
import Typography from "@material-ui/core/Typography";
import Paper from "@material-ui/core/Paper";

function MyCard({ title }) {

  return (
    <CardActionArea onClick={quadrantClickHandler}>
      <Card>   
          <CardContent>
            <Typography>{title}</Typography>
          </CardContent>

      </Card>
    </CardActionArea>
  );
}

function quadrantClickHandler(e) {
    e.stopPropagation();
    console.log('>> event.target ',e.target);
    //the idea here is that I will click a "card" 
    //and then determine which card was clicked so that 
    //I can highlight it similar to a radio box set in a form.
 }

function Quadrants() {
  return (
    <React.Fragment>
      <MyCard 
      title={
         <ul>
           <li>A</li>
           <li>B</li>
           <li>C</li>
           <li>D</li>
           <li>E</li>
           <li>F</li>
           <li>G</li>
         </ul>

       } />
      <MyCard title="Fast but expensive" />
      <MyCard title="Slow but Cheap" />
      <MyCard title="Slow but Fast" />
    </React.Fragment>
  );
}

function FourQuadrants() {
  const classes = useStyles();

  return (
    <div>
    <h2>Make a choice:</h2>
    <Paper className={classes.paper}>
      <Typography className={classes.top}>Big</Typography>
      <Typography className={classes.bottom}>Small</Typography>
      <Typography align="center" className={classes.left}>Expensive</Typography>
      <Typography align="center" className={classes.right}>Cheap</Typography>
      <Quadrants />
    </Paper>
    </div>
  );
}

export default FourQuadrants;

1 个答案:

答案 0 :(得分:1)

您可以让点击处理程序了解所有重要信息,而不是尝试从事件目标中提取信息。

下面的示例中的关键方面是:

  • 在最高级别(selectedId)上进行说明,以跟踪选择了哪张卡
  • 知道其卡片id并相应设置selectedId的点击处理程序
  • 我为每张卡提供了自己的idselectedId,以便它可以根据是否被选择来改变自身的样式
import ReactDOM from "react-dom";
import React from "react";
import Card from "@material-ui/core/Card";
import CardContent from "@material-ui/core/CardContent";
import CardActionArea from "@material-ui/core/CardActionArea";
import Typography from "@material-ui/core/Typography";
import { makeStyles } from "@material-ui/core";

const useStyles = makeStyles({
  selected: {
    border: "1px solid green"
  }
});

function MyCard({ title, id, selectedId, handleClick }) {
  const classes = useStyles();
  return (
    <Card className={id === selectedId ? classes.selected : null}>
      <CardActionArea onClick={handleClick(id)}>
        <CardContent>
          <Typography>{title}</Typography>
        </CardContent>
      </CardActionArea>
    </Card>
  );
}

function Quadrants() {
  const [selectedId, setSelectedId] = React.useState();
  const handleClick = id => e => {
    setSelectedId(id);
  };
  const cardProps = { selectedId, handleClick };
  return (
    <React.Fragment>
      <MyCard
        {...cardProps}
        id={1}
        title={
          <ul>
            <li>A</li>
            <li>B</li>
            <li>C</li>
            <li>D</li>
            <li>E</li>
            <li>F</li>
            <li>G</li>
          </ul>
        }
      />
      <MyCard {...cardProps} id={2} title="Fast but expensive" />
      <MyCard {...cardProps} id={3} title="Slow but Cheap" />
      <MyCard {...cardProps} id={4} title="Slow but Fast" />
    </React.Fragment>
  );
}

function FourQuadrants() {
  return (
    <div>
      <h2>Make a choice:</h2>
      <Quadrants />
    </div>
  );
}

function App() {
  return <FourQuadrants />;
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Edit selected card