DEVELOP
article thumbnail

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


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

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

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

 

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

 

부모 컴포넌트 

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

<javascript />
import ToggleMenu from "../components/ToggleMenu"; const Diary = () => { ... return ( <div className="Diary"> ... <ToggleMenu id={id} /> ... ) }; export default Diary;

 

자식 컴포넌트 

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

<javascript />
const [open, setOpen] = useState(false);

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

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

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

- 메뉴 버튼에 ref 지정

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

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

<javascript />
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에 값에 따라 다르게 설정하여, 클릭 시 투명도를 조절함 

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

 

최하위 자식 컴포넌트

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

 

 

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

<javascript />
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