MouseNext/PageRouter - 1. 라우팅,프리패칭

CodeModel·2024년 11월 11일
0

MouseNext

목록 보기
1/11

[id].tsx

pages > book 폴더 하위를 기준으로 한다.
[id].tsx를 할 경우 book/id 가 나올 경우 그에 맞는 id에 하나에 대응 하는 페이지를 보여준다.
[...id].tsx를 할 경우 book/id/name/day 등 모든 데이터를 /를 기준으로 잘라 배열로 가져올 수 있다. -> catch all segment
하지만 두 경우 모두 /book 뒤에 /가 아무것도 없다면 대응 할 수 없다.
[[...id]].tsx를 할 경우 대응 할 수 있다. -> optional catch all segment

import { useRouter } from "next/router";

const Page = () => {
  const router = useRouter();
  console.log(router); // query.id 에 url에 입력한 쿼리스트링이 있다.

  const { id } = router.query;
  return <h1>Book {id}</h1>;
};

export default Page;

api

pages > api 폴더 내부에는 next.js가 서버와 통신할 파일을 자체적으로 만들 수 있다.

/**
 * localhost:3000/api/hello 로 요청을 보낼 시 이곳에서 응답한다
 * 특별한 상황이 아니면 자주 사용하지 않는다
 */
import type { NextApiRequest, NextApiResponse } from "next";

type Data = {
  name: string;
};

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<Data>
) {
  res.status(200).json({ name: "John Doe" });
}

페이지 라우팅

Link / router.push - Client Side Rendering 으로 페이지를 이동시킨다

공용화

src > app.tsx 는 root 컴포넌트이다(모든 페이지의 부모 페이지)
Component : 현재 페이지 역할을 할 컴포넌트를 받는다
pageProps : Component에 전달할 Props를 저장한 객체

// _app.tsx
import type { AppProps } from "next/app";

export default function App({ Component, pageProps }: AppProps) {
  return (
    <GlobalLayout>
      <Component {...pageProps} />
    </GlobalLayout>
  );
}

// GlobaLayout.tsx
import Link from "next/link";
import { ReactNode } from "react";
import style from "./global-layout.module.css";

export default function GlobalLayout({ children }: { children: ReactNode }) {
  return (
    <div className={style.container}>
      <header/>
      <main>{children}</main>
      <footer/>
    </div>
  );
}

프리패칭

프리페칭 - 사전에 미리 불러온다.
현재 보고있는 페이지에서 링크들로 연결되어있는 페이지를 미리 불러와 사용자들이 페이지 이동을 빠르게 할 수 있도록 해준다 그렇기 때문에 Client Side Rendering처럼 빠르게 페이지 이동이 가능하다
개발자도구 -> 네트워크탭에서 확인 가능
npm run build를 통해 페이지별로 출력된 빌드 결과로 용량을 확인할 수 있다. 빌드를 해야 프로덕션 모드에 적용이 되는듯 하다
npm run start를 통해 프로덕션 모드로 실행 가능
npm run dev 는 개발자 모드이다

// 특정 페이지를 프리페칭 하는 코드. /test 페이지를 프리페칭한다
router.prefetch("/test");

{/* Link는 자동으로 프리페칭이 진행된다. */}
{/* 하단은 Link의 기능. 해당 페이지는 프리페칭 하지 않는다 */}
<Link href={"/search"} prefetch={false}>

특정 컴포넌트에 보이기

// home.tsx
import SearchableLayout from "@/components/SearchableLayout";
import { ReactNode } from "react";

export default function Home() {
  return <div>보여줄 해당 컴포넌트</div>;
}

/**
 * Home 컴포넌트도 결국 함수이고 함수는 객체이다.
 * 그렇기 때문에 메서드를 사용할 수 있고 아래의 메서드는 page 리액트 컴포넌트를
 * <SearchableLayout> 이라는 태그에 감싸져서 나오게 한다
 * 이렇게 하면 특정 컴포넌트를 특정 layout에 감싸진 형태로 나오게 할 수 있다.
 */
Home.getLayout = (page: ReactNode) => {
  return <SearchableLayout>{page}</SearchableLayout>;
};

이후

// _app.tsx
type NextPageWithLayout = NextPage & {
  getLayout: (page:ReactNode) => ReactNode;
};

export dfault function App({Component,pageProps,}: AppProps & {
  Component: NextPageWithLayout;
}) {
  // ?? 연산자는 왼쪽이 null이나 undefined이면 오른쪽을 반환한다
  const getLayout = Component.getLayout ?? ((page: ReactNode)=>page);
  
  return (
  	<GlobalLayout>
      {getLayout(<Component {...pageProps}/>)}
    </GlobalLayout>
  )
}

input onKeyDown

input 태그에 onKeyDown을 사용하면 e 객체를 받을 수 있고 이곳에서 엔터키를 분기처리 하여 엔터를 누를 시 검색이 되는 input을 만들 수 있다.

const onKeyDown = (e: React.ChangeEvent<HTMLInputElement>) => {
	if(e.key === "Enter") {
    	onSubmit(); // 실제로 데이터를 보내는 함수 
    }
}

<input onKeyDown={onKeyDown}/>

CSS -> ::before

평소 Overlay를 따로 구현했다면 이제 그럴 필요가 없어 보인다. ::before를 통해 Overlay를 더 쉽게 구현 할 수 있다.

.cover {
  background-position : center;
  background-repeat: no-repeat;
  background-size: cover;
  
  position: relative;
}

// cover의 overlay를 만들기 위해 가상요소를 사용한다
.cover::before {
  position: absolute;
  background-color: rgba(0,0,0,0.7);
}

// cover css 내부의 img 태그를 선택한다
.cover > img {
  z-index: 1;
  max-hight: 350px;
  height: 100%;
}
profile
개발자가 되기 위한 일기

0개의 댓글