본문 바로가기
  • 삽질하는 자의 블로그
메인-프로젝트/Next.js - 오늘 뭐먹지? 프로젝트

3. Layout 구성하기

by 이게뭐당가 2022. 12. 2.

웹페이지에는, 기본적으로 Layout 즉, Footer와, Header 가, 필요하지유!

 

Layout 컴포넌트를, 만들어서, "전체 애플리케이션의 바깥쪽에, 붙여줄겁니다"

 

< /pages/_app.js>

import "../styles/globals.css";
import Layout from "../components/ui/layout/layout";

function MyApp({ Component, pageProps: { session, ...pageProps } }) {
  return (
      <Layout>
        <Component {...pageProps} />
      </Layout>
  );
}

export default MyApp;
이런식으로 말이지요! 그렇게하면, Layout 를 "전역" 에서 사용 가능할 겁니다.
Layout 은 모든곳에 필요하니까요!

 

<Component / UI / layout > 폴더를 만들어줍니다. 그리고 그곳에 레이아웃 컴포넌트 작업을 시작할겁니다.

 

Layout은, Header, Footer 로 구성되어 있고,  Mobile 용은 따로 만들것이니까

Header-M , Header-W 두가지 버젼이 필요합니다.

 

import LayoutHeaderForMobile from "./layout-header-for-mobile";
import LayoutHeaderForWeb from "./layout-header-for-web";
import styles from "./layout-header.module.css";

function LayoutHeader() {
  return (
    <div>
      <header className={styles.headerForWeb}>
        <LayoutHeaderForWeb />
      </header>
      <header className={styles.headerForMobile}>
        <LayoutHeaderForMobile />
      </header>
    </div>
  );
}
export default LayoutHeader;

이게, 전체 Layout의 완성본이 될것입니다.

하나하나 만들어봅시다.

 

1. Layout Header for Web

 

제 레이아웃에는, 커서를 Hover 하면 나타날, DropDown 이 두개, 필요합니다.

 

"State" 를 통해, "상태를 관리" 하여, DropDown 이 나타날 상태인지 아닌지 판단합니다.

 

import { useState } from "react";

function LayoutHeaderForWeb(props) {
  const [show, setShow] = useState(false);
  const [showUser, setShowUser] = useState(false);

  let authenticatedId;
  if (session) {
    authenticatedId = session.user.email;
  }

  function showDropDown() {
    setShow(true);
  }

  function closeDropDown() {
    setShow(false);
  }

  function showUserDropDown() {
    setShowUser(true);
  }
  function hideUserDropDown() {
    setShowUser(false);
  }

 

Show의 State변경 함수, setShow 는, "기존 상태" 파라미터로 받습니다.

 

저 hide와 , show 를 합쳐서

 

   function dropDownToggle(){

     setShow(prev => !prev)

   }

 

이라고 해도 됩니다. 다만, 저는, Hover 의 트리거가 다르기 때문에, 이렇게 따로 두개로 뺐습니다~

 

1. 열리는 DropDown은, onMouseOver 리스너를 사용하여, 올리면 짠!

2.  닫히는 DropDown은, onMouseLeave 리스너를 사용하여, 낼리면 빰!

        <li className={styles.li} onMouseOver={showDropDown}>
            <div onMouseLeave={closeDropDown}>
              뭐먹지
              {show && <DropDown />}
            </div>
          </li>

3. && 연산자를 사용하여, "두 조건이 전부 참이면 뒤에 것을 실행한다" 라는 조건을 이용해, show 가 true 가 될 경우만,

   DropDown 이 생성됩니다.

 

이제 DropDown 을 만들어주고 붙여주면됩니다.

 

2. Layout Header for Mobile

 

모바일 버젼의 경우 클릭하는 형태의 DropDown 을 사용하고,

 

햄버거 버튼을 눌렀을때, 전체 화면을 어둡게 칠해놓고, 위에 메뉴를 띄워야 하기 때문에 

 

필요한 요소들은

 

1. position : absoulte 로, 전체 화면 덮기

2. z-index 로, 화면 우선순위 결정하기

3. 클릭 리스너로, DropDown 내리기

4. 햄버거 버튼을 누르면, Modal 과 함께, 메뉴가 생성되고,

5. 어떤 버튼을 누르더라도, Modal 은 자동으로 꺼지도록

 
function LayoutHeaderForMobile(props) {
  const [show, setShow] = useState(false);
   const [modal, setModal] = useState(false);
  function showModal() {
    setModal((prev) => !prev);
  }
  function showDropDown() {
    setShow((prev) => !prev);
  }

어떤 버튼을 눌러, 페이지를 이동하더라도, 분명히, Modal(덮은 화면) 이 꺼져야 하기 때문에,

Modal 은 모든 버튼에 달아줍니다.

 

...

      {modal && (
        <div className={styles.mainmodal}>
          <div className={styles.background}></div>
          <div className={styles.maindiv}>
            <h2>메뉴</h2>
 
           ...

 

     
            <li onClick={showDropDown}>
                <div>뭐먹지</div>
                {show && (
                    <div className={styles.dropdown}>
                      <ul>
                        <Link href={"/allfoods"}>
                          <li onClick={showModal}>카테고리별</li>
                        </Link>
                         <Link href={"/allfoods/tags"}>
                            <li onClick={showModal}>태그별</li>
                          </Link>
                          <Link href={"/random"}>
                              <li onClick={showModal}>랜덤 선택기</li>
                           </Link>
                         </ul>
                       </div>

리스트를 클릭하면, DropDown 이 나오고, 

숨겨져있던 메뉴들이 나옵니다.

 

역시나 && 연산자를 이용하여, 조건문으로 작성합니다.

 

Footer 도 비슷하게 만들어줍니다.

 

 

댓글