首页 > 解决方案 > 我如何只希望单击的项目出现在模式上?

问题描述

我是初学者。提前感谢您分享您的知识。

通过接收 Api 数据,我正在制作一个很棒的搜索应用程序。

但我有一个问题。不出现单击项目的模式屏幕。

确切地说,出现了模态屏幕。但是出现了我没有点击的其他东西。

通过在 Api 中找到数据 id 的路径,在屏幕上显示模态的工作方法。

这是问题的文件。搜索.jsx

import styled from "styled-components";
import SearchForm from "../Components/SearchForm";
import Portal from "../Components/Portal";
import Modal from "../Components/Modal";

const Search = () => {
  const [searchTerm, setSearchTerm] = useState("");
  const [cocktails, setCocktails] = useState([]);
  const [open, setOpen] = useState(false);

  const handleOpen = (e) => {
    setOpen(true);
  };
  const handleClose = () => {
    setOpen(false);
  };
  useEffect(() => {
    const getDrinks = async () => {
      try {
        const response = await fetch(
          `https://www.thecocktaildb.com/api/json/v1/1/search.php?s=${searchTerm}`
        );
        const data = await response.json();
        setCocktails(data);
      } catch (error) {
        console.log(error);
      }
    };
    getDrinks();
  }, [searchTerm]);

  return (
    <main style={{ width: "100%" }}>
      <SearchForm setSearchTerm={setSearchTerm} />
      <Wrapper className="cocktail-list">
        {cocktails.drinks.map(({ idDrink, strDrink, strDrinkThumb }) => (
          <>
            <Container
              className="cocktail"
              onClose={handleClose}
              onClick={handleOpen}
            >
              <Img>
                <img src={strDrinkThumb} alt={strDrink} />
              </Img>
              <Name key={idDrink}>{strDrink}</Name>
            </Container>
            {open && (
              <Portal>
                <Modal idDrink={`${idDrink}`} onClose={handleClose} />⭐
              </Portal>
            )}
          </>
        ))}
      </Wrapper>
    </main>
  );
};

export default Search;

⭐ 这是模态部分。我只想显示模态单击的项目。

但是,传递给 Modal 的 props 会发出cocktails.drinks.

这个文件是 Modal.jsx

import React, { useState, useEffect } from "react";
import axios from "axios";
import styled from "styled-components";
import Detail from "../Screens/Detail";

const MyModal = ({ onClose, idDrink }) => {
  const [data, setData] = useState([]);
  let id = idDrink;
  let url = `https://www.thecocktaildb.com/api/json/v1/1/lookup.php?i=${id}`;
  useEffect(() => {
    axios
      .get(url)
      .then((res) => {
        setData(res.data.drinks);
      })
      .catch((error) => {
        console.log(error);
      });
  }, [url]);
  return (
    <MyModals onClick={onClose}>
      <Detail idDrink={idDrink} />
    </MyModals>
  );
};

export default MyModal;

Search.jsx(问题文件)交给Id来传播模态信息。

如何获取点击项的 id 并将其交给 Modal.jsx?

标签: reactjsapionclickreact-hooksmodal-dialog

解决方案


您需要在 Search 组件的状态中存储所选项目的 id,然后将该 id 传递给 Modal 组件。

import styled from "styled-components";
import SearchForm from "../Components/SearchForm";
import Portal from "../Components/Portal";
import Modal from "../Components/Modal";

const Search = () => {
  const [searchTerm, setSearchTerm] = useState("");
  const [cocktails, setCocktails] = useState([]);
  const [open, setOpen] = useState(false);


  const [selectedItem, setSelectedItem] = useState("");


  const handleOpen = (idDrink) => {
    setSelectedItem(idDrink)
    setOpen(true);
  };
  const handleClose = () => {
    setOpen(false);
  };
  useEffect(() => {
    const getDrinks = async () => {
      try {
        const response = await fetch(
          `https://www.thecocktaildb.com/api/json/v1/1/search.php?s=${searchTerm}`
        );
        const data = await response.json();
        setCocktails(data);
      } catch (error) {
        console.log(error);
      }
    };
    getDrinks();
  }, [searchTerm]);

  return (
    <main style={{ width: "100%" }}>
      <SearchForm setSearchTerm={setSearchTerm} />
      <Wrapper className="cocktail-list">
        {cocktails.drinks.map(({ idDrink, strDrink, strDrinkThumb }) => (
          <>
            <Container
              className="cocktail"
              onClose={handleClose}
              onClick={() => handleOpen(idDrink)}
            >
              <Img>
                <img src={strDrinkThumb} alt={strDrink} />
              </Img>
              <Name key={idDrink}>{strDrink}</Name>
            </Container>
          </>
        ))}

// You should keep modal outside the loop. Because it's rendering multiple Modals inside the loop and show all of them at once. When you trigger the hanldeOpen function.
 
      {open && (
              <Portal>
                <Modal idDrink={`${selectedItem}`} onClose={handleClose} />⭐
              </Portal>
            )}
      </Wrapper>
    </main>
  );
};

export default Search;

推荐阅读