웹페이지에는, 기본적으로 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 도 비슷하게 만들어줍니다.