DEVELOP
article thumbnail

일기장 프로젝트에서 구현한  간단한 모달 메뉴 사용을 정리하고자 한다.


# 모달 메뉴가 있는 컴포넌트 (부모)  : Diary.js

# 모달 메뉴 버튼 컴포넌트 (하위자식) : ToggleMenu.js

# 모달 메뉴 버튼을 클릭했을 때 나오는 메뉴 컴포넌트 (최하위 자식) : EditAndRemove.js

 

순으로 컴포넌트가 이루어져 있다. 

 

부모 컴포넌트 

-> id props를 넘겨주면서 자식 컴포넌트를 호출한다. 

import ToggleMenu from "../components/ToggleMenu";

const Diary = () => {
 ...
    return (
      <div className="Diary">
        ...
        <ToggleMenu id={id} />
        ...
        )
};

export default Diary;

 

자식 컴포넌트 

- open의 값이 true이면 메뉴가 열리고, false이면 닫히도록 state 이용

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

- menu button에 onClick() 함수로 toggleOpen() 함수를 넘겨준다. 

- 현재 값이 true이면 false로 바꾸고, false이면 true로 바꾸도록 setState 해준다.

  const toggleOpen = () => {
    setOpen(!open);
  };

- 메뉴 버튼에 ref 지정

  const menuRef = useRef();
      <button className={"menu_btn"} onClick={toggleOpen} ref={menuRef}>

- 현재 마우스의 클릭이 메뉴 영역으로 벗어나면 ( 외부 영역 클릭하면 ) 메뉴 닫히도록 구현

  useEffect(() => {
    const onClickOutside = (e) => {
      if (open && !menuRef.current.contains(e.target)) {
        setOpen(false);
      }
    };

    document.addEventListener("click", onClickOutside);
    return () => {
      document.removeEventListener("click", onClickOutside);
    };
  }, [open]);

- 메뉴 이미지의 className을 open에 값에 따라 다르게 설정하여, 클릭 시 투명도를 조절함 

        <img
          className={open ? "menu_img_clicked" : "menu_img"}
          src={process.env.PUBLIC_URL + `/assets/menu.png`}
          alt="menu"
        />
.ToggleMenu .menu_img_clicked {
  opacity: 0.5;
}

 

최하위 자식 컴포넌트

- 메뉴에 띄우고자 하는 내용을 구현하면 된다. 

 

 

자식 컴포넌트 (모달 호출 컴포넌트) 전체 코드

import { useState, useRef, useEffect } from "react";
import EditAndRemoveMenu from "./EditAndRemoveMenu";

const ToggleMenu = ({ id }) => {
  const [open, setOpen] = useState(false);
  const menuRef = useRef();

  const toggleOpen = () => {
    setOpen(!open);
  };

  useEffect(() => {
    const onClickOutside = (e) => {
      if (open && !menuRef.current.contains(e.target)) {
        setOpen(false);
      }
    };

    document.addEventListener("click", onClickOutside);
    return () => {
      document.removeEventListener("click", onClickOutside);
    };
  }, [open]);

  return (
    <div className="ToggleMenu">
      <button className={"menu_btn"} onClick={toggleOpen} ref={menuRef}>
        <img
          className={open ? "menu_img_clicked" : "menu_img"}
          src={process.env.PUBLIC_URL + `/assets/menu.png`}
          alt="menu"
        />
      </button>
      {open && <EditAndRemoveMenu id={id} />}
    </div>
  );
};

export default ToggleMenu;
profile

DEVELOP

@JUNGY00N