Подгрузка данных SWAPI в модальное окно

Есть карточки персонажей с краткой информацией о них. При нажатии на карточку всплывает модальное окно с подробной информацией о персонаже, на чью карточку нажали.

В карту персонажа идёт подгрузка данным со SWAPI, после повторных запросов к серверу быть не должно. Как подгрузить данные из карточки в модальное окно?

И ещё вопрос: в зависимости от пола персонажа нужна определенная иконка в модальном окне. Как это можно реализовать?

Код прилагаю:

/*SWAPI.js*/

import React, { useState, useEffect } from 'react';
import '../styles/main.css';
import './card/style.css';
import image from '../img/1680499747_3-112.jpg';
import Modal from '../components/modal/Modal';

function Swapi() {


    const [modalInfoIsOpen, setModalInfoOpen] = useState(false);

    const [people, setPeople] = useState([]);



    useEffect(() => {
        const fetchPeople = async () => {
            try {
                const response = await fetch('https://swapi.dev/api/people/');
                const data = await response.json();
                setPeople(data.results);
            } catch (error) {
                console.error(error);
            }
        };

        fetchPeople();

    }, []);



    return (
        <>
            <Modal
                isOpen={modalInfoIsOpen}
                onClose={() => setModalInfoOpen(false)}
            >

            </Modal >

            <h2 className="title-1">{people.length} Characters</h2>
            <div className="projects">
                {people.map(person => (
                    <div key={person.name} className='project'
                        onClick={() => setModalInfoOpen(true)}>
                        <img src={image} alt={person.name} className='project__img' />
                        <div className='project_text'>
                            <h2>{person.name}</h2>
                            <p>Height: {person.height}</p>
                            <p>Mass: {person.mass}</p>
                            <p>Gender: {person.gender}</p>
                        </div>

                    </div>
                ))}

            </div>
        </>
    );
};


export default Swapi;


/*Modal.js*/

import './Modal.css';
import { ReactComponent as IconClose } from "../../img/closeButton.svg";
import imageModal from '../../img/female.png';

const Modal = ({ isOpen, onClose, children }) => {

    const onWrapperClick = (event) => {
        if (event.target.classList.contains('modal-wrapper')) onClose()
    }
    return (

        <>
            {isOpen && (
                <div>
                    <div className="modal">
                        <div className="modal-wrapper" onClick={onWrapperClick}>
                            <div className="modal-content">
                                <img src={imageModal} alt='icon male/female' />
                                Swapi();
                                <div className="modal-contenv-text">

                                    <h2>Hello</h2>
                                    <p>This is the information about</p>

                                </div>
                                <button className="modal-close-button"
                                    onClick={onClose}>
                                    <IconClose />
                                </button>
                                {children}
                            </div>
                        </div>
                    </div>
                </div>
            )}
        </>
    )
}

export default Modal

Обновляю информацию: Получилось выводить массив в модальное окно. Но как сделать выборки для конкретных персонажей? Нажимаешь на карточку - по идее нужно запомнить какой-то "ключ", который приведет к конкретному персонажу - применить это "ключ" - получить модальное окно с персонажем, на которого кликнул.

Код прилагаю:


/*SWAPI*/
import React, { useState, useEffect } from 'react';
import Modal from '../modal/Modal';

import '../../styles/main.css';
import './swapi.css';

import image from '../../img/1680499747_3-112.jpg';
// import imageModal from '../../img/female.png';

export default function SWAPI() {

    const [modalInfoIsOpen, setModalInfoOpen] = useState(false);

    const [people, setPeople] = useState([]);
    const [key, setKey] = useState();

    useEffect(() => {
        const fetchPeople = async () => {
            try {
                const response = await fetch('https://swapi.dev/api/people/');
                const data = await response.json();
                setPeople(data.results);
            } catch (error) {
                console.error(error);
            }
        };

        fetchPeople();


    }, []);


    const handleInfoPerson = (e) => {
        setPeople(e.data.people);
        setKey(e.data.key);
    };

    // function genderType(gender) {
    //     if (gender === 'female') {
    //         return <img src={imageModal} alt='icon male/female' />
    //     } else {
    //         <img sra={image} alt='icon male' />
    //     }

    // };



    return (
        <>
            <Modal
                isOpen={modalInfoIsOpen}
                onClose={() => setModalInfoOpen(false)}
                infoPerson={people}
                infoPersonKey={key}
            >

            </Modal >

            <h2 className="title-1">{people.length} Characters</h2>
            <div className="projects">
                {people.map(person => (
                    <div key={person.name} className='project'
                        onClick={() => setModalInfoOpen(true)}
                        onChange={handleInfoPerson}
                    >
                        <img src={image} alt={person.name} className='project__img' />
                        {/* {genderType(person.gender)} */}
                        <div className='project_text' >
                            <h2>{person.name}</h2>
                            <p>Height: {person.height}</p>
                            <p>Mass: {person.mass}</p>
                            <p>Gender: {person.gender}</p>

                        </div>

                    </div>
                ))}



            </div>
        </>
    )
}

/*Modal.js*/



import './Modal.css';
import { ReactComponent as IconClose } from "../../img/closeButton.svg";
import imageModal from '../../img/female.png';





const Modal = ({ isOpen, onClose, children, infoPerson, infoPersonKey }) => {

    const onWrapperClick = (event) => {
        if (event.target.classList.contains('modal-wrapper')) onClose()
    }
    return (
        <>
            {isOpen && (
                <div>

                    <div className="modal">
                        <div className="modal-wrapper" onClick={onWrapperClick}>
                            <div className="modal-content">

                                <img src={imageModal} alt='icon male/female' />

                                <div className="modal-contenv-text" >

                                    <h2>Hello, { }</h2>
                                    {infoPerson.map(person => (

                                        < div key={person.name} className='project' >

                                            <div className='project_text' >
                                                <h2>{person.name}</h2>
                                                <p>Height: {person.height}</p>
                                                <p>Mass: {person.mass}</p>
                                                <p>Gender: {person.gender}</p>

                                            </div>

                                        </div>
                                    ))}


                                </div>
                                <button className="modal-close-button"
                                    onClick={onClose}>
                                    <IconClose />
                                </button>
                                {children}
                            </div>
                        </div >
                    </div >
                </div >
            )}
        </>
    )
}

export default Modal



Ответы (0 шт):