javascript - React dan Material UI: bagaimana saya bisa memperluas hanya satu kartu saja


Saya menggunakan React dan Material UI untuk menampilkan beberapa kartu yang dipetakan. Ketika saya mencoba memperluas sebuah kartu, semua kartu diperluas sekaligus. Saya mengetahui bahwa saya harus melewatkan sebuah indeks ke dalam fungsi "handleExpandClick" saya, tetapi masih tidak berhasil. Mungkin saya melakukan semacam kesalahan ketik.

Saya menemukan pertanyaan ini Perluas satu kartu saat diklik yang berkaitan dengan masalah yang sama, tetapi tampaknya tidak berlaku untuk situasi saya.

Ini potongan kode saya:

const useStyles = makeStyles(theme => ({
  card: {
    maxWidth: 345,
    marginBottom: 15
  },
  media: {
    height: 0,
    paddingTop: "56.25%" // 16:9
  },
  expand: {
    transform: "rotate(0deg)",
    marginLeft: "auto",
    transition: theme.transitions.create("transform", {
      duration: theme.transitions.duration.shortest
    })
  },
  expandOpen: {
    transform: "rotate(180deg)"
  },
  avatar: {
    width: 90
  },
  root: {
    display: "flex",
    justifyContent: "center",
    flexWrap: "wrap",
    "& > *": {
      margin: theme.spacing(0.5)
    }
  },
  list: {
    width: 200
  }
}));

const ItininerariesList = ({ itineraries, activities }) => {
  const classes = useStyles();
  const [expanded, setExpanded] = React.useState(false);

  let path = window.location.pathname;
  let currentId = path.substring(path.lastIndexOf("/") + 1);

  const itinerariesPerCity = itineraries.filter(
    itiner => itiner.city_id === currentId
  );


  const handleExpandClick = () => {
    setExpanded(!expanded);
  };


  return (
    <Fragment>
      {itinerariesPerCity.map((itinerary, i) => (
        <Card className={classes.card} key={itinerary._id}>
          <CardHeader
            avatar={
              <Grid
                container
                direction="column"
                justify="flex-start"
                alignItems="center"
                className={classes.avatar}
              >
                <Avatar
                  aria-label="user"
                  alt={itinerary.profile_name}
                  src={itinerary.profile_img}
                >
                  <PersonIcon />
                </Avatar>
                <Typography variant="caption" component="p">
                  {itinerary.profile_name}
                </Typography>
              </Grid>
            }
            action={
              <IconButton aria-label="settings">
                <MoreVertIcon />
              </IconButton>
            }
            title={itinerary.title}
            subheader={itinerary.sub_title}
          />

          <CardContent>

          </CardContent>
          <CardActions disableSpacing>
            <IconButton aria-label="add to favorites">
              <FavoriteIcon />
            </IconButton>
            <IconButton aria-label="share">
              <ShareIcon />
            </IconButton>
            <IconButton
              className={clsx(classes.expand, {
                [classes.expandOpen]: expanded
              })}
              onClick={() => handleExpandClick()}
              aria-expanded={expanded}
              aria-label="show more"
            >
              <ExpandMoreIcon />
            </IconButton>
          </CardActions>
          <Collapse in={expanded} timeout="auto" unmountOnExit>
            <CardContent>
              <ActivitiesList
                activities={activities}
                itineraryId={itinerary._id}
              />
            </CardContent>
          </Collapse>
        </Card>
      ))}
    </Fragment>
  );
};

export default ItininerariesList;

Setiap saran atau panduan akan sangat dihargai. Terima kasih sebelumnya.

Jawaban #1

Dalam handler expand Anda memang harus mengoper indeks. Dan juga menggunakannya dalam state. Sesuatu seperti ini:

const [expandedId, setExpandedId] = React.useState(-1);

...

  const handleExpandClick = (i) => {
    setExpandedId(expandedId === i ? -1 : i);
  };

  ...


          <CardContent />
          <CardActions disableSpacing>
            <IconButton aria-label="add to favorites">
              <FavoriteIcon />
            </IconButton>
            <IconButton aria-label="share">
              <ShareIcon />
            </IconButton>
            <IconButton

              onClick={() => handleExpandClick(i)}
              aria-expanded={expandedId === i}
              aria-label="show more"
            >
              <ExpandMoreIcon />
            </IconButton>
          </CardActions>
          <Collapse in={expandedId === i} timeout="auto" unmountOnExit>
            <CardContent>
              <div>ActivitiesList</div>
            </CardContent>
          </Collapse>

Berikut adalah contoh yang berfungsi: https://codesandbox.io/s/eloquent-sara-wswrn