이전 작업(React-Router) 에서 라우터를 설정해줬으니 이제 라우터를 통한 다른페이지 이동을 설정해줘야된다. 메뉴를 만들어야되는데 일단 간단하게 만들어놓고 이후에 내가 만들고싶은 슬라이드 메뉴를 구현해보고자 한다.
메뉴판을 만들기전에 메뉴컴포넌트를 만들어야된다.
먼저 메뉴가 들어갈 자리 MenuSection
을 만들어주고
메뉴 버튼이 보이고 버튼을 눌렀을때 숨겨진 메뉴가 나타나고 기존의 버튼 아이콘이 변화 하는 형식으로 나타냈다.
Menu.js
const Menu = () => { const [open, setOpen] = useState(false); const [visible, setVisible] = useState(false); return ( <div className={cn("MenuSection")}> {visible && ( <div className={cn("hideMenuSection")}> <ul className={cn("hideMenuUl")}> <li className={cn("Menulist")}> <Link className={cn("MenuLink")} to="/Login"> Login/Join </Link> </li> <li className={cn("Menulist")}> <Link className={cn("MenuLink")} to="/"> Home </Link> </li> <li className={cn("Menulist")}> <Link className={cn("MenuLink")} to="/Map"> Map </Link> </li> <li className={cn("Menulist")}> <Link className={cn("MenuLink")} to="/Bug"> Bug </Link> </li> <li className={cn("Menulist")}> <Link className={cn("MenuLink")} to="/Notice"> Notice </Link> </li> <li className={cn("Menulist")}> <Link className={cn("MenuLink")} to="/About"> About us </Link> </li> </ul> </div> )} <button className={cn("MenuButton")} onClick={() => { setVisible(!visible); }} visible={visible} {visible ? ( <IoMdClose className={cn("closeButton")} /> ) : ( <FiMenu className={cn("openButton")} /> )} </button> </div> ); }; export default Menu;
핵심 Point
useState
Hooks로 상태값 변화를 주어서 Button
의 초기값을 false로 설정하여 버튼을 누르기전에는 숨겨진 메뉴가 보이지않고 메뉴를 클릭했을시 True값으로 바뀜면서 메뉴가 바뀌게 된다.const [visible, setVisible] = useState(false);
visible
의 상태에 따라서 아이콘의 모습이 변화한다.<button className={cn("MenuButton")} onClick={() => { setVisible(!visible); }} visible={visible} {visible ? ( <IoMdClose className={cn("closeButton")} /> ) : ( <FiMenu className={cn("openButton")} /> )} </button>
{visible && (<div className={cn("hideMenuSection")}>
visible 이 True일때 나타나는 Section hideMenuSection
Button.scss
$lightblue: #3ea8ff; $deepblue: #156fb9; $darkblue: rgb(12, 86, 129); //⭐⭐⭐⭐아주 아주 중요한 사실⭐⭐⭐ // z-index를 설정하기 위해서는 position: relative가 필수적임. .MenuSection { height: 40px; font-size: 15px; margin-top: -24px; overflow: hidden; color: coral; overflow: visible; z-index: 400; .MenuButton { margin-top: 10px; background-color: white; width: 40px; height: 40px; cursor: pointer; align-items: center; justify-content: center; position: absolute; left: 50%; transform: translate(-50%, 10%); -webkit-transform: scaleX(29%, 100%); color: $darkblue; border-radius: 20%; outline: none; display: flex; align-items: center; justify-content: center; transition: 0.1s all linear; border: solid 0.1em rgb(192, 192, 192); box-shadow: 1px 1px rgb(206, 206, 206); // &:hover { // background: #156fb9; // } // &:active { // background: #3ea8ff; // } .closeButton { display: flex; font-size: 30px; position: relative; color: red; &:hover { .MenuSection { background-color: #3ea8ff; } } } .openButton { display: flex; font-size: 40px; display: flex; font-size: 30px; &:hover { .MenuButton { background: #ff9696; } } } &.visible { .openButton { display: flex; } .closeButton { display: flex; color: red; border: none; z-index: 4; } .MenuSecion { background-color: white; width: 20px; overflow: visible; } background: #ff5151; &:hover { background: #ff9696; } &:active { background: #fa5252; } transform: translate(-50%, 50%); transition: 0.3s all linear; animation-duration: comparable(10, 10); } } .hideMenuSection { overflow: hidden; height: auto; background-color: #ffffff; z-index: 204; width: 100%; justify-content: center; align-content: center; text-align: center; object-fit: contain; border-bottom: 1px solid #424242; transition: all 0.5s; .hideMenuUl { z-index: 40; align-items: center; //수직 중앙 정렬 justify-content: center; //수평 중앙 정렬 text-align: center; display: inline; flex-direction: row; position: relative; color: white; .Menulist { text-align: center; font-size: 25px; font-family: "BebasNeue-Regular"; font-weight: 200; letter-spacing: 2px; text-decoration: none; padding-bottom: 2vh; .MenuLink { color: black; font-weight: 600; text-decoration: none; z-index: 40; &:hover { text-decoration: underline; transform: translate(-50%, 20%); transition: 0.3s; } } &:nth-child(1) { padding-top: 3.4vh; } } } } }
scss 코드 중간 중간 필요없는 부분도 있습니다. 참고해주세용
Home.js
const Home = () => { const [showNav, setShowNav] = useState(false); return ( <div className={cn("Home")}> <ProgressBar /> <div className={cn("MenuSection")}> <Menu /> </div> <div className={cn("Head")}> <Header /> </div> <div className={cn("Body")}> <Calendar /> </div> <div className={cn("Festival")}> <Festival /> </div> </div> ); };
이제 완성된 Menu컴포넌트를 Home컴포넌트에 옮겨서 적용하기만 하면 완벽하게 구현이 된다.