이전 작업(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컴포넌트에 옮겨서 적용하기만 하면 완벽하게 구현이 된다.
