넥스트

NEXT

https://nextjs.org/learn

NEXT 14를 사용하자

리액트 베이스의 풀스택이다!

폴더가 라우터다

alt text

(폴더이름)내 맘대로 만들고
그안에 들어가는 구성요소는 page, layout, template 이름 고정이다
ex) about 폴더

1. mkdir app/about  (Route Folder)
2. make app/about/layout.tsx 
3. make app/about/page.tsx
4. nav to page from Home(app/page.tsx) 

서버에서 이루어진다.

위쪽에 “use client”는 Next.js 13 이상에서 도입된 기능으로, 컴포넌트가 클라이언트 컴포넌트임을 명시하는 선언입니다.

프리티어(위에 임포트 순서 설정)

.prettierrc

{
  "singleQuote": true,
  "jsxSingleQuote": true,
  "semi": true,
  "trailingComma": "es5",
  "plugins": ["@trivago/prettier-plugin-sort-imports"],
  "importOrder": [
    "^next$",
    "^next/\\w*$",
    "^next/(.*)$",
    "^react$",
    "^react/(.*)$",
    "^@/lib/(.*)$",
    "^[./]"
  ]
}

>에서 importOrder의 내부 순서를 바꾸어주면 import되는것들의 순서를 지정해줄 수 있다.

yarn dev

yarn build -> yarn start

차이를 알아두기(dev에서는 계속 시간같은거 업데이트 가능하지만, start에서는 배포용이라서 딱 그 시점?이 올라감, 따라서 다이나믹하게 만들어줘야함)

useRouter (only Client Component)

'use client'; > 이거는 이제 클라이언트(=브라우저)에서 실행이 되게끔한다!!!
//클라이언트 컴포넌트에서는 어싱크(async)를 못 쓴다.


// useRouter
import { useRouter } from 'next/navigation'
const router = useRouter()
router.push('/dashboard', { scroll: false });

// another functions
router.back();

useSearchParam

??

다이나믹하게 페이지

// /hi/[time]/page.tsx                            
export default function HiTime({ params }: { params: { time: string } }) {
  return <div>Good {params.time}!</div>
}

()는 경로에 영향을 미치지 않음(정리용)

/app
  /(auth)
    /login/page.tsx
  /dashboard/page.tsx

여기서 (auth)는 그냥 더 가독성 좋게 보일려고하는거임

인터셉트

client router와 server router를 다르게 표현
next/link/Link를 이용해야 intercepting 됨.
A → B(intercept) → B(refresh)
(.)   같은 레벨/depth
(..)  하나 위 레벨
(...) Root 레벨
(..)(..)  두개 위 레벨

원래 원본의 파일이 있는데 그 파일로 이동하는 것이 아닌 내가 만든 인터셉트 페이지로 이동을 시킨다(이것은 새로고침하면 원본페이지로 이동이 된다),

(.)/ (..) / (…) 같은경우는 그냥 폴더 위치에 따른 경로 느낌

[[]] 대괄호 두개


[[...params]]와 같은 형태는 Next.js에서 Catch-All 라우팅을 사용할 때, 대괄호를 2개 사용하는 방식입니다. 이것은 동적 경로를 정의할 때 매우 유용합니다. 대괄호 두 개([[...]])는 특정 경로가 **선택적 동적 경로(선택적 Catch-All)**임을 의미합니다.

1. [...params] (Catch-All 라우팅):
설명: [...]를 사용하면 URL의 나머지 부분을 하나의 배열로 캡처할 수 있습니다.
예시: /pages/blog/[...slug].tsx
이 경우, blog 경로의 하위 모든 경로가 slug 배열로 캡처됩니다.
예를 들어:
/blog/hello/world → { slug: ['hello', 'world'] }
/blog/my-post → { slug: ['my-post'] }
2. [[...params]] (선택적 Catch-All 라우팅):
설명: 대괄호 두 개([[...]])를 사용하면 선택적 동적 경로가 됩니다. 즉, 이 경로는 있어도 되고 없어도 되는 선택적 경로입니다.
예시: /pages/blog/[[...slug]].tsx
이 경우, blog 경로는 동적 경로가 없어도 매칭이 됩니다.
예를 들어:
/blog → { slug: [] } (빈 배열)
/blog/hello/world → { slug: ['hello', 'world'] }
/blog/my-post → { slug: ['my-post'] }
요약:
[...params]: Catch-All 동적 경로로서, 지정한 경로 이후의 모든 부분을 배열로 캡처합니다.
[[...params]]: 선택적 Catch-All 동적 경로로서, 경로가 있어도 되고 없어도 됩니다. 경로가 없을 경우 빈 배열로 반환됩니다.
이 패턴을 통해 유연한 라우팅을 구성할 수 있으며, 다양한 경로 변형을 처리하는 데 매우 유용합니다.

use client 와 asyncs는 같이 사용을 못한다.

"use client"와 async 함수는 각자 다른 환경에서 동작하기 때문에, 서버 컴포넌트와 클라이언트 컴포넌트의 특성 차이로 인해 제약이 발생합니다.
> 왜 use client와 async를 함께 사용할 수 없을까?
클라이언트 컴포넌트는 동기적으로 렌더링:

Next.js에서 클라이언트 컴포넌트는 브라우저에서 동기적으로 렌더링됩니다. 클라이언트 컴포넌트는 동기적인 렌더링 흐름을 가져야 하기 때문에 컴포넌트 자체가 async 함수가 될 수 없습니다.
만약 컴포넌트 전체가 async로 선언되면, 해당 컴포넌트가 반환할 때까지 기다려야 하는데, 이는 브라우저의 동기 렌더링 흐름과 맞지 않기 때문에 에러가 발생합니다.
데이터 가져오기와 렌더링의 분리:

클라이언트 컴포넌트에서는 데이터 가져오기를 위해 React hooks를 사용해야 합니다. useEffect, useState 같은 React hooks로 비동기 작업을 처리하고, 상태 업데이트를 통해 다시 렌더링해야 합니다.
서버 컴포넌트에서는 서버에서 데이터를 미리 가져온 후 그 결과를 클라이언트로 넘겨주지만, 클라이언트 컴포넌트는 브라우저에서 비동기 작업을 별도로 처리하고 렌더링 흐름을 제어해야 합니다.

Image를 사용하기 위한 설정

// for Image component in next.config.mjs

/** @type {import('next').NextConfig} */
const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'via.placeholder.com',
        port: '',
        pathname: '/**',
      },
    ],
  },
};

export default nextConfig;

Next Cloudinary Image(사진) 편집???

https://next.cloudinary.dev/

shadcn 설치!!!

https://ui.shadcn.com/docs/installation/next

pnpm dlx shadcn@latest init

아이콘 패키지 설치!!

https://heroicons.com/

$> pnpm add @heroicons/react

Next-auth 설치

$> pnpm add next-auth@beta
$> pnpm dlx auth secret 
>> .env.local의 AUTH_SECRET 자동 세팅!