본문 바로가기

Libraries/React

[React] 버튼을 클릭시 모달창(팝업창) 컴포넌트 뜨게 하기, 닫기(취소) 버튼 누르면 없어지게 하기, useState props로 전달하기 , props 사용하여 state를 다른 컴포넌트로 전달하기

728x90

 

 

버튼을 클릭하면 모달창이 열기/닫기할 수 있는 기능을 구현해보자!

 

 

 

 

 만들 예제의 완성본 

 

상단에 장바구니 담기 버튼을 누르면 모달창이 뜬다. (배경도 어두워지고 배경에 있는 것들은 클릭 안됨)
그리고 취소 버튼을 누르면 모달창이 없어지고, 배경도 다시 원래 색으로 변한다.

 

 

 

 

 


 

 

 

 

 

 1. 모달창 컴포넌트를 만든다. 

 

 

 Modal.jsx  라는 컴포넌트를 만들고, 여기에   Modal.css  파일을 import해서 style을 적용한다.

그리고   App.js 에   Modal .jsx  컴포넌트를 import해서 렌더링한다.

 

 

 Modal.jsx 

import "./Modal.css";

export const Modal = () => {
  return (
    <div className="Overlay">
      <div className="cart-container">
        <span className="product-name">[풀무원] 국물 떡볶이</span>
        <span className="product-price">4,000원</span>
        <div className="count">
          <div className="minus">-</div>
          <div className="number">2</div>
          <div className="plus">+</div>
        </div>
        <span className="total">합계</span>
        <span className="total-price">8,000원</span>
        <button className="cancle" type="button">
          취소
        </button>
        <button className="add-cart" type="button">
          장바구니 담기
        </button>
      </div>
    </div>
  );
};

 

<div className="Overlay"> 로 전체를 감싸서, 모달창 클릭하면 배경 어두워지게 하기 위해 배경을 Overlay로 감싼다.

 

 

 

  Modal.css 

.Overlay {
  position: fixed;
  width: 100%;
  height: 100%;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.4);
  z-index: 9999;
}

.cart-container {
  background-color: #ffffff;
  width: 250px;
  height: 150px;
  border: 1px solid #cccccc;
  border-radius: 20px;
  padding: 20px;
  position: relative;
  font-weight: 600;
  box-shadow: 0 3px 6px rgba(0, 0, 0, 0.16), 0 3px 6px rgba(0, 0, 0, 0.23);
  position: fixed;
  z-index: 100;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

.product-name {
  display: inline-block;
  font-size: 14px;
  position: absolute;
}

.product-price {
  font-size: 14px;
  position: absolute;
  left: 20px;
  top: 60px;
}

.count {
  width: 70px;
  height: 20px;
  border: 1px solid #cccccc;
  position: relative;
  position: absolute;
  right: 20px;
  top: 50px;
  border: 1px solid #cccccc;
  padding: 2px 0;
}

.minus {
  position: absolute;
  left: 10%;
}

.number {
  position: absolute;
  left: 45%;
}

.plus {
  position: absolute;
  right: 10%;
}

.total {
  display: inline-block;
  position: absolute;
  left: 20px;
  top: 100px;
  font-size: 14px;
}

.total-price {
  font-size: 15px;
  display: inline-block;
  position: absolute;
  right: 20px;
  top: 50%;
  font-size: 22px;
  font-weight: 600;
}

.cancle {
  position: absolute;
  left: 20px;
  bottom: 20px;
  width: 120px;
  padding: 7px 0;
  background-color: white;
  color: #0f6cfc;
  font-weight: 600;
  border: 1px solid #0f6cfc;
  border-radius: 5px;
}

.add-cart {
  position: absolute;
  right: 20px;
  bottom: 20px;
  width: 120px;
  padding: 7px 0;
  background-color: #0f6cfc;
  color: white;
  font-weight: 600;
  border: 1px solid #0f6cfc;
  border-radius: 5px;
}

 

모달창 만드는 법(HTML,CSS)에 대해서 자세히 알고싶으신 분은 아래 링크의 게시글을 참고해주세요!

https://dev-ini.tistory.com/17

 

 

 

 App.js 

import { Modal } from "./Modal";

export default function App() {
  return (
    <div>
      <Modal />
    </div>
  );
}

 

 

 

 

 2. App.js에 "장바구니 담기" 버튼 만들기 

 

 

 App.js 

import { Modal } from "./Modal";
import "./styles.css";

export default function App() {
  return (
    <div>
      <button type="button" className="add-cart-button">
        장바구니 담기
      </button>
      <Modal />
    </div>
  );
}

 

 

 styles.css 

.add-cart-button {
  all: unset;
  margin-top: 100px;
  margin-left: 230px;
  padding: 10px 20px 10px 20px;
  background-color: white;
  color: #333333;
  font-weight: 600;
  border: 1px solid #a6a6a6;
  border-radius: 5px;
  cursor: pointer;
}

.add-cart-button:hover {
  border: 1px solid #0f6efc;
  color: #0f6cfc;
}

 

 

 

 

 3. 장바구니 담기 버튼을 누르면 모달창이 열리게 하기 

 

 모달창 열리게 만드는 코드 

(전체 코드 밑부분에 이 코드에 대한 자세한 설명이 있습니다)

 

 

 App.js 

import { useState } from "react";
import { Modal } from "./Modal";
import "./styles.css";

export default function App() {
  const [openModal, setOpenModal] = useState(false);

  return (
    <div>
      <button
        type="button"
        className="add-cart-button"
        onClick={() => {
          setOpenModal(true);
        }}
      >
        장바구니 담기
      </button>
      {openModal ? <Modal /> : null} // state가 true면 모달창이 보이게 된다.
    </div>
  );
}

 

 

 코드 순서 및 설명 

 

(1) state를 생성하고, 초기값을 false로 설정하여 모달창을 숨김상태로 만든다.

const [openModal, setOpenModal] = useState(false);

 

 

(2) <button>에 onClick 이벤트를 달아서 버튼을 클릭하면, state가 true로 바뀌게 만든다. 

      <button
        type="button"
        className="add-cart-button"
        onClick={() => {
          setOpenModal(true);  // state 반전시키기
        }}
      >
        장바구니 담기
      </button>

 

 

(3) 삼항연산자를 이용해서 Modal 컴포넌트의 state가 true가 되면 모달창이 화면에 보이게 만들고, false가 되면 화면에 안보이게 만든다.

{openModal ? <Modal /> : null}

 

 

 

 모달창 열기 구현 영상 

 

 

 

 

 

 4. 닫기 버튼을 누르면 모달창이 닫히게 하기 

 

 모달창 닫히게 하는 코드 

(전체 코드 밑부분에 이 코드에 대한 자세한 설명이 있습니다)

 

 

 App.js 

import { useState } from "react";
import { Modal } from "./Modal";
import "./styles.css";

export default function App() {
  const [openModal, setOpenModal] = useState(false);

  return (
    <div>
      <button
        type="button"
        className="add-cart-button"
        onClick={() => {
          setOpenModal(true);
        }}
      >
        장바구니 담기
      </button>
      // App.js에서의 state를 Modal 컴포넌트에 props로 전달한다.
      {openModal ? <Modal openModal={openModal} setOpenModal={setOpenModal} /> : null} 
    </div>
  );
}

 

 

 Modal.jsx 

import "./Modal.css";


export const Modal = ({ openModal, setOpenModal }) => { // props를 전달받는다.
  return (
    <div className="Overlay">
      <div className="cart-container">
        <span className="product-name">[풀무원] 국물 떡볶이</span>
        <span className="product-price">4,000원</span>
        <div className="count">
          <div className="minus">-</div>
          <div className="number">2</div>
          <div className="plus">+</div>
        </div>
        <span className="total">합계</span>
        <span className="total-price">8,000원</span>
        <button
          className="cancle"
          type="button"
          onClick={() => {
            setOpenModal(false); // 클릭 이벤트로 모달창 닫히게 하기
          }}
        >
          취소
        </button>
        {!openModal ? setOpenModal(true) : null} // state 반전시키기
        <button className="add-cart" type="button">
          장바구니 담기
        </button>
      </div>
    </div>
  );
};

 

 

 코드 순서 및 설명 

 

(1)  App.js에서의 state를 Modal 컴포넌트에 props로 전달한다.

{openModal ? <Modal openModal={openModal} setOpenModal={setOpenModal} /> : null}

 

 

(2)  Modal.jsx에서 props를 전달 받는다.

export const Modal = ({ openModal, setOpenModal }) => {

 

 

(3) 취소 <button>에 onClick 이벤트를 달아서 버튼을 클릭하면, state가 false로 바뀌게 만든다. (모달창이 닫히게끔 만들기)

<button
  className="cancle"
  type="button"
  onClick={() => {
    setOpenModal(false); // 클릭 이벤트로 모달창 닫히게 하기
  }}
>
  취소
</button>

 

 

(4) 삼항연산자를 이용해서 Modal 컴포넌트의 state가 false면, state를 true로 바꾸게 만든다. (toggle)

<button
  className="cancle"
  type="button"
  onClick={() => {
    setOpenModal(false);
  }}
>
  취소
</button>
{!openModal ? setOpenModal(true) : null} // state 반전시키기

 

 

 모달창 닫기 구현 영상 

 

 

 

728x90