Вывод модального окна для конкретного объекта из массива

У меня имеется массив из объектов и при нажатии на кнопку содержащую значение ключа name, должно открываться модальное окно конкретно для этого объекта. В начале у меня открывалось модальное окно, но не закрывалось. Оказалось проблема в том что я задал для них всех одно состояние и при изменении его состояния открывались все модальные окна и последнее перекрывало оставшиеся, поэтому ничего не работало. Теперь вместо состояния я передал тот массив с объектами, также для каждого добавил ключ чтобы отдельно регулировать их модальные окна. Но теперь при нажатий на кнопку у меня ломается сайт и появляется следующая ошибка. введите сюда описание изображенияМожете объяснить где я делаю ошибку, перепробовал много вариантов и прямо чувствую что не учитываю чего-то, но что не могу понять. Вот код данного компонента:

import React, {useState} from 'react';

function Career() {

    let [isOpen, setIsOpen] = useState([
        {
            id: 1,
            name: "Микро кредитная организация",
            position: "Помощник главного менеджера",
            duration: "01.06.2019-29.08.2019",
            description: "На данной работе в моей главной обязанностью была оценка клиентов перед выдачей кредита. " +
                "А точнее, проверка данных клиента написанных при заявке на кредит. Для этого собирал информацию о клиенте из множество государственных и " +
                "личных баз данных финансовых организаций. При корректности данных и соответствий требованиям, составлял досье и отправлял комитету" +
                "для принятия окончательного решения о согласий или отказе в выдаче кредита.",
            placeImg: "microcredit.png",
            modal: false
        },
        {id: 2...},
        {id: 3...}
    ]);

    function SwitchModal(id) {
        setIsOpen(isOpen.map(workplace => {
                if (workplace.id === id) {
                    workplace.modal = !workplace.modal
                }
            })
        )
    }

    return (
        <div className="workWrapper" style={{
            display: "flex",
            flexDirection: "column",
            justifyContent: "center",
            height: "100%",
            marginTop: "50px",
            paddingBottom: "20px",
            width: "100%"
        }}>
            {isOpen.map(workplace => {
                return <div key={workplace.id}>
                    <div style={{display: "flex", justifyContent: "space-between"}}>
                        <button style={{border: 0}} className="workPlaceNameText"
                                onClick={() => SwitchModal(workplace.id)}>{workplace.name}</button>
                        {workplace.modal && (<div className="modal">
                                <div className="modal-body">
                                    <p className="">{workplace.position + "  "}<span style={{
                                        color: "white",
                                        textDecoration: "underline"
                                    }}>{workplace.duration}</span></p>
                                    <p className="">{workplace.description}</p>
                                    <button onClick={() => SwitchModal(workplace.id)}>adadadad</button>
                                </div>
                            </div>
                        )}
                    </div>
                    <span className="line"/>
                </div>
            })
            }
        </div>
    );
}

export default Career;

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

Автор решения: Lev Shportak

Советую вам разбивать кучи сложно читаемого кода на компоненты, и в полную силу использовать механики реакта. Декомпозируйте. Я накидал код для примера, на его основе можете понять подход.

import React, {useState} from 'react';

function App() {
  const [careersData, setCareersData] = useState([
    {
        id: 1,
        name: "Микро кредитная организация",
        position: "Помощник главного менеджера",
        duration: "01.06.2019-29.08.2019",
        description: "На данной работе в моей главной обязанностью была оценка клиентов перед выдачей кредита. " +
            "А точнее, проверка данных клиента написанных при заявке на кредит. Для этого собирал информацию о клиенте из множество государственных и " +
            "личных баз данных финансовых организаций. При корректности данных и соответствий требованиям, составлял досье и отправлял комитету" +
            "для принятия окончательного решения о согласий или отказе в выдаче кредита.",
        placeImg: "microcredit.png",
    }
]); 
  return (
    <div>
      {careersData.map(career => {
        <Career key = {career.id} {...career}/>
      })}
    </div>
  );
}

function Career({name, ...otherCareerData}) {
  const [isOpen, setIsOpen] = useState(false)
  
  return (
    <div>
      <div style={{display: "flex", justifyContent: "space-between"}}>
        <button style={{border: 0}} className="workPlaceNameText"
          onClick={() => setIsOpen(true)}>{workplace.name}</button>
          <CareerModal isOpen = {isOpen} setIsOpen = {setIsOpen} 
             {...otherCareerData} />
      </div>
    </div>
  );
}

function CareerModal({isOpen, setIsOpen, position, duration, description}) {  
  
  return (
    <div>
      <div className={'modal-body' (isOpen ? 'visibleClass': 'hideClass') }>
          <p className="">{position + "  "}<span style={{
              color: "white",
              textDecoration: "underline"
          }}>{duration}</span></p>
          <p className="">{description}</p>
          <button onClick={() => setIsOpen(false)}>adadadad</button>
      </div>
    </div>
  );
}
→ Ссылка