Как динамически создать кнопку для вызова определенного действия, используя массив карт в реакции - PullRequest
3 голосов
/ 04 июля 2019

Я попытался отобразить массив в реагировать и попытался сгенерировать кнопку, которая будет выполнять определенное действие, которое ссылается на другой object, сгенерированный тем же массивом, с использованием map() function.I ' Я использую Material-UI для ускорения процесса разработки.

Я новичок в реагировании (на самом деле это мой первый проект с реагированием), так что, возможно, это просто вопрос реализации 'состояния' в реакции, но я немного сбиваю с толку использование this и bind синтаксис правильно.

П.С. -Так что извините за мою глупость:>

Перейдите по этой ссылке , чтобы воспроизвести код

и вот код, с которым у меня возникли проблемы:


const products = [
  {
    id: 1,
    img: "https://image.flaticon.com/icons/png/512/676/676434.png",
    title: "Pineaple",
    price: "Rp. 14.000",
    desc: "Pineaple is one of nutritious food"
  },
  {
    id: 2,
    img: "https://image.flaticon.com/icons/png/512/676/676433.png",
    title: "Banana",
    price: "Rp. 14.000",
    desc: "Banana is one of nutritious food"
  },
  {
    id: 3,
    img: "https://image.flaticon.com/icons/png/512/676/676441.png",
    title: "Dragonfruit",
    price: "Rp. 14.000",
    desc: "Dragonfruit is one of nutritious food"
  },
];


export default function Posts(props) {

  const [open, setOpen] = React.useState(false);

  function handleClickOpen() {
    setOpen(true);
  }

  function handleClose() {
    setOpen(false);
  }
  return (
    <div>
      <Grid container spacing={1} justify="center">

        {products.map(product => (
          <Grid item xs={6} sm={3} md={2} key={product.id}>
            <Card>
              <CardActionArea>
                <CardMedia
                  component="img"
                  width="auto"
                  height="auto"
                  image={product.img}
                />
                <CardContent>
                  <Typography component="h2"> {product.title} </Typography>
                  <Typography variant="body2" color="primary" component="p">
                    {" "}{product.price}{" "}
                  </Typography>
                </CardContent>
              </CardActionArea>
              <CardActions>
                <Button onClick={handleClickOpen}>
                  Buy
                </Button>
              </CardActions>
            </Card>
          </Grid>
        ))}
      </Grid>

      {products.map(product => (
        <Dialog
          key={product.id}
          fullScreen
          open={open}
          onClose={handleClose}
        >
          <AppBar position="sticky">
            <Toolbar>
              <IconButton onClick={handleClose}>
                <CloseIcon />
              </IconButton>
              <Typography> {product.title} </Typography>
              <Button onClick={handleClose}> buy </Button>
            </Toolbar>
          </AppBar>
          <List className={classes.dialogue}>
            <img src={product.img} alt={product.title} />
            <ListItem button>
              <ListItemText primary={product.title} secondary={product.desc}/>
            </ListItem>
          </List>
        </Dialog>
      ))}

    </div>
  );
}

Я хочу сделать onclick кнопку, сгенерированную сопоставленным массивом для ссылки на конкретное действие (показать определенный диалог в списке массивов). Я также хочу реализовать тот же метод для onSubmit на кнопке «купить» в диалоге.

Скриншот: https://imgur.com/a/M4v5LOu (Я нажимаю «купить» на «pineaple», но реагирую на рендеринг всего списка и показываю последний объект в списке «dragonfruit».)

Полагаю, я буду использовать redux, но, возможно, не сейчас.

Во всяком случае, все, я очень ценю любой ответ и помогает :) Спасибо!

Ответы [ 2 ]

1 голос
/ 04 июля 2019

Есть несколько способов решить эту проблему, но я покажу вам один. Вы используете React Hooks, и у вас есть ловушка для установки состояния открытия / закрытия. В моем решении я делаю небольшую модификацию, добавляя еще один крючок для установки выбранного продукта, а затем проверяю, установлены ли оба продукта - открытый и *.

export default function Posts(props) {
  const classes = useStyles();
  const [open, setOpen] = React.useState(false);
  const [product, setProduct] = React.useState(null);

  function handleClickOpen(event, item) {
    event.persist();
    setProduct(item);
    setOpen(true);
  }

  function handleClose() {
    setOpen(false);
  }
  return (
    <div style={{ margin: 0, padding: 0 }}>
      <Grid container spacing={1} justify="center">
        {products.map(product => (
          <Grid item xs={6} sm={3} md={2} key={product.id}>
            <Card elevation={0}>
              <CardActionArea>
                <CardMedia
                  component="img"
                  width="auto"
                  height="auto"
                  image={product.img}
                />
                <CardContent>
                  <Typography component="h2"> {product.title} </Typography>
                  <Typography variant="body2" color="primary" component="p">
                    {' '}
                    {product.price}{' '}
                  </Typography>
                </CardContent>
              </CardActionArea>
              <CardActions>
                <Button
                  variant={'outlined'}
                  size="small"
                  color="primary"
                  onClick={event => handleClickOpen(event, product)}
                >
                  Buy
                </Button>
              </CardActions>
            </Card>
          </Grid>
        ))}
      </Grid>
      {open && product && (
        <Dialog
          key={product.id}
          className={classes.dialogue}
          fullScreen
          open={open}
          onClose={handleClose}
          BackdropProps={{ classes: { root: classes.root } }}
          PaperProps={{ classes: { root: classes.paper } }}
        >
          <AppBar position="sticky">
            <Toolbar>
              <IconButton
                edge="start"
                color="inherit"
                onClick={handleClose}
                aria-label="Close"
              >
                <CloseIcon />
              </IconButton>
              <Typography variant="h6" className={classes.title}>
                {product.title}
              </Typography>
              <Button color="inherit" onClick={handleClose}>
                buy
              </Button>
            </Toolbar>
          </AppBar>
          <List className={classes.dialogue}>
            <Image
              className={classes.images}
              src={product.img}
              alt={product.title}
            />
            <ListItem button>
              <ListItemText primary={product.title} secondary={product.desc} />
            </ListItem>
          </List>
        </Dialog>
      )}
    </div>
  );
}

В вашем коде у вас не было возможности отследить выбранный в данный момент продукт, поэтому вы всегда получаете последний элемент в цикле. Используя другой хук для выбранного продукта, я могу отслеживать выбранный продукт. Я надеюсь, что это поможет вам и удачи в вашем мастерстве в React.

0 голосов
/ 04 июля 2019

У вас открыты и закрыты два состояния.

Вы используете карту в массиве и показывает диалоговое окно.

Диалоговое окно откроется, когда состояние открытия равно true.Это будет верно для всех элементов в массиве.Диалоговое окно будет показано для всех элементов.Теперь они будут накладываться друг на друга, и вы сможете увидеть только последний.Когда вы нажимаете на закрывающее диалоговое окно, ваше открытое состояние устанавливается на false, и все диалоговые окна закрываются.

Подсказка: - Сохраняйте состояние, которое будет содержать идентификатор элемента, для которого должен отображаться диалог.Показывать диалог только тогда, когда состояние идентификатора совпадает с идентификатором элемента

...