본문 바로가기

공부/Next

Next.js 알아보기 2 (Link, useRouter, 예약 파일)

반응형

 

Link 📖

prefetching 지원

next.js의 `<Link>` 컴포넌트는 뷰포트에 링크가 나타나는 순간 해당 페이지의 코드와 데이터를 미리 가져오는 `prefetching`기능을 지원합니다. 사용자가 클릭했을 때 즉시 페이지를 볼 수 있게 합니다.

 

client-side navigation 지원

`<Link>` 컴포넌트는 새 페이지를 로드하기 위해 클라이언트 측에서 페이지를 바꿔주기 때문에 페이지 전환 시 빠른 사용자 경험을 제공합니다.

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import Link from "next/link";

const inter = Inter({ subsets: ["latin"] });

export const metadata: Metadata = {
  title: "Sparta Next App",
  description: "This is awesome Website",
};

export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="en">
      <body className={inter.className}>
        <nav>
          <Link href="/">Home</Link>
          <Link href="/about">About</Link>
          <Link href="/contact">Contact</Link>
          <Link href="/blog">Blog</Link>
        </nav>
        {children}
      </body>
    </html>
  );
}

 

useRouter 📖

useRouter를 사용할 때는 항상 코드 최상단에 `use client`를 삽입해야 합니다.

"use client";

import { useRouter } from "next/navigation";

export default function Test () {
  const router = useRouter();

  const handleButtonClick = () => {
    로직1();
    로직2();

    ...

    router.push("/new_location");
  }

  return <button onClick={handleButtonClick}>클릭!</button>
}

 

예약 파일 📖

layout

layout파일은 어떤 `segment`와 그 자식 노드에 있는 요소들이 공통적으로 적용받게 할 UI를 정의합니다. 그래서 반드시 `children prop`이 존재합니다.

 

특정 segment 이하의 route에서 적용 받을 layout UI를 해당 폴더 안에 만듭니다.

 

children을 포함 시켜서 공통 UI를 만듭니다.

export default function DashboardLayout({
  children, // will be a page or nested layout
}: {
  children: React.ReactNode
}) {
  return (
    <section>
      {/* Include shared UI here e.g. a header or sidebar */}
      <nav></nav>
 
      {children}
    </section>
  )
}

 

따라서 동일 layout안에서 다른 경로를 이동해도 `re-rendering`이 일어나지 않습니다. 따라서 `headers``footers``sidebars`처럼 바뀔 필요가 없는 경우에 유용합니다.

 

`template`과의 차이가 있으니 아래에서 설명하겠습니다

 

template

`layout`과 차이점은 상태를 유지하는가 리렌더링이 일어나는가입니다.

 

template은 라우팅을 탐색할 때 각 하위 항목에 대해 새 인스턴스를 만듭니다. 즉 DOM 요소가 다시 생성된다는 것을 의미합니다.

// src>app>text>layout.tsx
// src>app>text>template.tsx
"use client";

import Link from "next/link";
import React from "react";

const TestTemplate = ({ children }: { children: React.ReactNode }) => {

	useEffect(()=>{
		console.log("최초 렌더링 한 번만 호출");
	}, []);
	
  return (
    <div className="m-8 p-8 bg-white">
      <h1>테스트 페이지</h1>
      <p>테스트 경로 하위에서의 이동을 확인.</p>
      <nav>
        <ul>
          <li>
            <Link href="/test">테스트 페이지</Link>
          </li>
          <li>
            <Link href="/test/1">테스트 페이지 1</Link>
          </li>
          <li>
            <Link href="/test/2">테스트 페이지 2</Link>
          </li>
        </ul>
      </nav>
      {children}
    </div>
  );
};

export default TestTemplate;

 

`layout` : console.log가 최초 한 번만 호출됩니다.

`template` : 페이지 이동 시 계속 호출됩니다.

 

not-found

next.js에서는 우리가 별도 설정을 하지 않아도 기본 스타일이 된 `not found`에러 페이지를 제공합니다.

 

또한 app폴더 밑에 직접 만들 수도 있습니다.

// src>app>not-found.tsx
import React from "react";

const NotFound = () => {
  return <div>존재하지 않는 페이지입니다.</div>;
};

export default NotFound;

 

metadata & seo

next.js는 기본적으로 seo를 위한 `Metadata`를 설정할 수 있게 해 줍니다. html head에 삽입했던 많은 정보를 `metadata`는 객체 형태로 지원하고 있습니다.

 

리액트에서는 index.html파일이 존재하고 파일의 head 태그에 seo 향상을 위해 여러 `meta`,`link`태그 등 메타데이터를 작성해야 했습니다.

 

✨ 그러나, next.js에서는 `config-based metadata`를 활용할 수 있습니다.

 

static

 

`page.tsx` or `layout.tsx`에서 메타데이터 객체를 작성하고 export 해주면 됩니다.

export const metadata: Metadata = {
  title: "Sparta Next App",
  description: "This is awesome Website",
}

 

여기서 기억해야 할 점

 

metadata in page.tsx : 해당 page.tsx 컴포넌트에만 적용

metadata in layout.tsx : 해당 layout의 하위 요소에 모두 적용

 

dynamic

 

라우트에서 동적으로 변경되는 params를 기반으로 메타데이터를 변경하고 싶을 때 `generateMetadata function`을 사용하면 됩니다.

import React from "react";

type Props = {
  params: {
    id: string;
  };
};

export function generateMetadata({ params }: Props) {
  return {
    title: `Detail 페이지 : ${params.id}`,
    description: `Detail 페이지 : ${params.id}`,
  };
}

const TestDetailPage = ({ params }: Props) => {
  return <div>Detail 페이지 : {params.id}</div>;
};

export default TestDetailPage;

 

다음 게시물

 

 

Next.js 알아보기 3 (React Server Component, Client Component)

React Server Component & Client Component 📖✨ 기본적으로 `app`폴더 하위의 모든 컴포넌트는 `서버 컴포넌트`입니다! 서버 컴포넌트말 그대로 서버에서 실행되는 컴포넌트입니다.// src>app>page.tsxexport defau

mingos-habitat.tistory.com

 

반응형