[React] 위에서 아래로 내려오는 메뉴📜

: ) YOUNG·2021년 7월 22일
2

React

목록 보기
8/13
post-thumbnail

궁금하신 점이나 고칠 부분이 있다면 언제든지 댓글 남겨주세요!

이전 작업(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

  1. useState Hooks로 상태값 변화를 주어서 Button의 초기값을 false로 설정하여 버튼을 누르기전에는 숨겨진 메뉴가 보이지않고 메뉴를 클릭했을시 True값으로 바뀜면서 메뉴가 바뀌게 된다.
    const [visible, setVisible] = useState(false);
  1. 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컴포넌트에 옮겨서 적용하기만 하면 완벽하게 구현이 된다.

0개의 댓글