Skip to content

ZeroCho/next-app-router-z

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

68 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

ํด๋” ์„ค๋ช…

์ฝ”๋“œ๋ฅผ ์ผ์ผ์ด ์ž…๋ ฅํ•˜์ง€ ์•Š๊ณ  ์ด ํด๋”๋“ค์—์„œ ๋งŽ์ด ๋ณต์‚ฌํ•ด์˜ต๋‹ˆ๋‹ค. ์ผ์ผ์ด ์ž…๋ ฅํ•  ์ˆ˜๊ฐ€ ์—†๋Š”๊ฒŒ, svg ๊ฐ™์€ ํƒœ๊ทธ๋„ ์žˆ๊ณ  css๋„ ๋„ˆ๋ฌด ๋งŽ์Šต๋‹ˆ๋‹ค. ์ œ๊ฐ€ ๋ญ”๊ฐ€๋ฅผ ๋ณต์‚ฌํ•œ๋‹ค๊ณ  ํ•˜๋ฉด ์—ฌ๋Ÿฌ๋ถ„๋“ค๋„ ์—ฌ๊ธฐ์„œ ๋ณต์‚ฌํ•ด์˜ค์„ธ์š”.

๊ธฐ์กด ์ œ ๋‹ค๋ฅธ ํด๋ก  ์ฝ”๋”ฉ ๊ฐ•์ขŒ๋ฅผ ์ƒ๊ฐํ•˜๊ณ  ๋”ฐ๋ผ์น˜๊ธฐ ์œ„ํ•ด ๋“ค์œผ์‹œ๋ฉด ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ์ผ๋ก€๋กœ ๋ฆฌ์•กํŠธ ๋…ธ๋“œ๋ฒ„๋“œ ๊ฐ•์˜๋ณด๋‹ค ์ฝ”๋“œ๋Ÿ‰์ด 3๋ฐฐ ์ •๋„ ๋” ๋งŽ์•„์„œ ๋”ฐ๋ผ์น˜๊ธฐ๋ณด๋‹ค๋Š” ๋ณต์‚ฌํ•˜๋ฉด์„œ ์„ค๋ช…ํ•˜๋Š” ๋ฐฉ์‹์„ ์ทจํ–ˆ์Šต๋‹ˆ๋‹ค.

ch0 ํด๋”์—์„œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์‹œ๋Š” ๊ฒƒ์„ ๊ฐ•๋ ฅํžˆ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

  • ch0: ์ดˆ๊ธฐ ์„ธํŒ…("css module์„ ์„ ํƒํ•œ ์ด์œ " ๊ฐ•์˜๊ฐ€ ๋๋‚ฌ์„ ๋•Œ์˜ ์ฝ”๋“œ - ์ด ํด๋”๋ฅผ ๋ณต์‚ฌํ•ด์„œ ์‹œ์ž‘ํ•˜์‹œ๋ฉด ํŽธํ•ฉ๋‹ˆ๋‹ค)
  • ch1: ์„น์…˜1์ด ์™„๋ฃŒ๋œ ์ฝ”๋“œ
  • ch2-1: ์„น์…˜2์˜ "classnames๋กœ ํด๋ž˜์Šค ํ•ฉ์„ฑํ•˜๊ธฐ"๊นŒ์ง€์˜ ์†Œ์Šค ์ฝ”๋“œ
  • ch2-2: ์„น์…˜2๊ฐ€ ์™„๋ฃŒ๋œ ์†Œ์Šค ์ฝ”๋“œ
  • ch3-1: ์„น์…˜3์˜ next-auth๊ฐ€ ์ ์šฉ๋œ ์†Œ์Šค ์ฝ”๋“œ
  • ch3-2: ์„น์…˜3์˜ react query ์ธํ”ผ๋‹ˆํŠธ ์Šคํฌ๋กค๋ง์ด ์ ์šฉ๋œ ์†Œ์Šค ์ฝ”๋“œ
  • ch4: ๋ฐฐํฌ ์ง์ „ ์†Œ์Šค ์ฝ”๋“œ(ํฌํŠธ 80์œผ๋กœ ๋ฐ”๊พธ๊ธฐ ์ „)
  • lecture: ๊ฐ•์˜ ์™„์„ฑ๋ณธ ์ฝ”๋“œ(๋ฒ„๊ทธ๊ฐ€ ์ข€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฒ„๊ทธ ํ•ด๊ฒฐ์€ ์•„๋ž˜ z-com ๋ ˆํฌ์ง€ํ† ๋ฆฌ์—์„œ ๊พธ์ค€ํžˆ ํ•˜๊ณ ์žˆ์–ด์š”.)
  • z-com: z.nodebird.com ๋ฐฐํฌ ์†Œ์Šค ์ฝ”๋“œ(๋‹ต๊ธ€, ์žฌ๊ฒŒ์‹œ, ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ… ๋“ฑ๋“ฑ์ด ์™„์„ฑ๋˜์–ด ์žˆ์–ด์š”!)

์ˆ˜๊ฐ•์ƒ๋ถ„๋“ค์˜ ๊ฐ•์˜๋…ธํŠธ

์ €๋ณด๋‹ค ๋” ์ •๋ฆฌ๋ฅผ ์ž˜ ํ•ด๋‘์‹  ๋ถ„๋“ค์˜ ๋…ธํŠธ์ž…๋‹ˆ๋‹ค. ๊ฐ™์ด ๋ณด์‹œ๋ฉด์„œ ๊ณต๋ถ€ํ•˜์‹œ๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ˆ˜๊ฐ•์ƒ ๋ฒ ์ŠคํŠธ ๊ฐ•์˜๋…ธํŠธ ๋งํฌ

Next App Router

๊ฐ€์žฅ ํฌ๊ฒŒ ๋‹ค๋ฅธ ์ 

  • ๊ฐ์ข… ํด๋” ์œ ํ˜• ์ถ”๊ฐ€๋กœ ๋””๋ ‰ํ† ๋ฆฌ ๋ผ์šฐํŒ…์ด ํŽธํ•ด์ง
  • ๋ ˆ์ด์•„์›ƒ ๊ธฐ๋Šฅ
  • ํŽ˜์ด์ง€๋ณ„ ๊ถŒํ•œ ์ฒดํฌ
  • ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ ๋ถ„๋ฆฌ๋กœ ์ธํ•œ ์ตœ์ ํ™”
  • ๋ฐ์ดํ„ฐ ์บ์‹œ
  • ์„œ๋ฒ„ ์•ก์…˜

ํด๋ก ์ฝ”๋”ฉ์˜ ์žฅ๋‹จ์ 

  • ํฌํŠธํด๋ฆฌ์˜ค๋กœ ์‚ฌ์šฉ ๊ธˆ์ง€(์ˆ˜๊ฐ•์ƒ๋“ค์ด ๊ฐ™์€ ๊ฑธ ๋งŽ์ด ์ œ์ถœํ•ด์„œ ๋ˆˆ์น˜์ฑ”)
  • ๋‡Œ ๋นผ๊ณ  ๋”ฐ๋ผ๋งŒ ํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์‹ค๋ ฅ์ด ์ „ํ˜€ ๋Š˜์ง€ ์•Š์Œ โ†’ ์Šค์Šค๋กœ ํ•ด๋ณผ ๊ฒƒ
  • HTML, CSS๋ฅผ ๊ฐœ๋ฐœ์ž๋„๊ตฌ๋ฅผ ํ†ตํ•ด ๊ณต๋ถ€ํ•  ์ˆ˜ ์žˆ๊ณ , HTTP ์š”์ฒญ๋„ ๋„คํŠธ์›Œํฌ ํƒญ์„ ํ†ตํ•ด ๋ถ„์„ํ•ด๋ณผ ์ˆ˜ ์žˆ์Œ.
  • ์•„์ด๋””์–ด๊ฐ€ ์•ˆ ๋– ์˜ค๋ฅผ ๋•Œ ์ข‹์€ ๋ฐฉ๋ฒ•์ž„. ๋ณดํ†ต์€ ์“ฐ๋˜ ๊ธฐ๋Šฅ๋งŒ ๊ณจ๋ผ์„œ ์“ฐ๋Š”๋ฐ ํด๋ก ์ฝ”๋”ฉ์„ ํ•˜๋‹ค๋ณด๋ฉด ์ฒ˜์Œ ๋ณด๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์˜จ๊ฐ– ์‹œ๋„๋ฅผ ํ•ด๋ณด๊ฒŒ ๋จ โ†’ ๊ณต์‹๋ฌธ์„œ๋ฅผ ์ž์„ธํ•˜๊ฒŒ ์ฝ๊ฒŒ ๋จ

ํ”„๋กœ์ ํŠธ ์„ธํŒ…ํ•˜๊ธฐ

์ฒ˜์Œ์— ์ง์ ‘ ์„ธํŒ…ํ•˜๊ธฐ๋ณด๋‹จ ch0 ํด๋” ๋‚ด๋ถ€ ๋‚ด์šฉ์„ ๋ณต์‚ฌํ•ด์„œ ์‹œ์ž‘ํ•˜์‹œ๋ฉด ํŽธํ•ฉ๋‹ˆ๋‹ค.

์™„์ „ ์ฒ˜์Œ๋ถ€ํ„ฐ ์„ธํŒ…ํ•˜์‹œ๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด...

  • ํ”„๋กœ์ ํŠธ ํด๋”๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์€ ๊ณณ์œผ๋กœ ๊ฐ€์„œ
npx create-next-app@latest
  • ๊ฐ•์˜์™€ ๊ฐ™๊ฒŒ ์„ ํƒํ•˜๊ธฐ

๊ธฐํš์ž์™€ ๋””์ž์ด๋„ˆ๊ฐ€ ๊ธฐํš์„œ๋ฅผ ๋˜์ ธ์ฃผ์—ˆ๋‹ค.

๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์„ฑํ•˜๊ธฐ

  • [username]์€ ์‚ฌ์šฉ์ž ํ”„๋กœํ•„
  • i/flow/signup, i/flow/login์ด๋‚˜ compose/tweet์€ ํŽ˜์ด์ง€ ์ „ํ™˜ ์—†์ด ๋ชจ๋‹ฌ ๋„์›Œ์•ผ ํ•จ
  • ๋กœ๊ทธ์ธ ํ›„์—๋Š” /home์œผ๋กœ redirect
  • /login๋„ /i/flow/login์œผ๋กœ redirect

page.tsx, layout.tsx, template.tsx

  • ์ด๋ฆ„์€ ๊ณ ์ •์ž„(๋ฐ”๊ฟ€ ์ˆ˜ ์—†์Œ)
  • layout.tsx์™€ template.tsx๋Š” ๊ณต์กดํ•  ์ˆ˜ ์—†์Œ
  • page.tsx๋Š” layout.tsx์˜ ์ž์‹์œผ๋กœ ๋“ค์–ด๊ฐ

Routing Group

  • (afterLogin), (beforeLogin) ํด๋”๋Š” ์‹ค์ œ๋กœ ๊ฒฝ๋กœ์— ๋ฐ˜์˜๋˜์ง€๋Š” ์•Š์Œ
  • ํ•˜์œ„ ํด๋”๋“ค์— layout ์ ์šฉ ์šฉ๋„

CSS Modules๋ฅผ ์“ฐ๋Š” ์ด์œ 

  • vanilla-extract๋ฅผ ์‚ฌ์šฉํ•˜๋ ค ํ–ˆ์œผ๋‚˜ Windows์—์„œ Server Component ์ง€์›ํ•˜์ง€ ์•Š์Œ ๋งํฌ
  • WSL์„ ์“ฐ๋ฉด ๋˜๋‚˜ Hot reloading์ด ๋ฌธ์ œ๊ฐ€ ์ƒ๊น€
  • ์ถ”ํ›„ ์ด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋˜๋ฉด vanilla-extract ๋„์ž… ์˜ˆ์ •(๋ณด๋„ˆ์Šค ๊ฐ•์˜์—์„œ ๋‹ค๋ฃน๋‹ˆ๋‹ค!)

layout์—์„œ ํ˜„์žฌ ๋ผ์šฐํŠธ ํ™•์ธํ•˜๊ธฐ

  const segment = useSelectedLayoutSegment();
  • layout์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ, page์—์„œ๋Š” ์‚ฌ์šฉ ๋ถˆ๊ฐ€(usePathname ์‚ฌ์šฉํ•  ๊ฒƒ)
  • ๋ฐ”๋กœ ํ•˜์œ„๋งŒ ๋‚˜์˜ด(compose/tweet์˜ ๊ฒฝ์šฐ compose๋งŒ ๋‚˜์˜ด)
  • ๋ชจ๋“  depth๋ฅผ ๊ฐ€์ ธ์˜ค๊ณ  ์‹ถ๋‹ค๋ฉด useSelectedLayoutSegments (['compose', 'tweet'])
  • layout์˜ state๋Š” ๋ชจ๋“  ํŽ˜์ด์ง€์— ๊ณต์œ ๋จ
  • ๊ณต์œ ํ•˜๊ธฐ ์‹ซ๋‹ค๋ฉด layout ๋Œ€์‹  template.tsx ์“ฐ๊ธฐ(๋งค๋ฒˆ ์ƒˆ๋กœ ๋ Œ๋”๋ง ๋จ)

parallel router, intercepting routes ์ ์šฉ

๋งํฌ

i/flow/signup๊ณผ i/flow/login์€ ์ด๊ฑธ๋กœ ์ฒ˜๋ฆฌ

  • @ ํด๋” ์•ˆ์— default.tsx ์žŠ์ง€ ๋ง๊ธฐ

i/flow/signup, i/flow/login ๋ชจ๋‹ฌ ์‹œ ์ฃผ์˜

  • (beforeLogin) ๋‚ด๋ถ€์˜ @modal ์•ˆ์— (.)/flow/signup์„ ๋งŒ๋“ค์–ด์•ผ ํ•จ
  • (beforeLogin)๊ณผ ๋™๋“ฑ ๋ ˆ๋ฒจ์— ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ The default export is not a React Component in page ์—๋Ÿฌ ๋ฐœ์ƒ
  • /login์—์„œ /i/flow/login์œผ๋กœ ๊ฐ€๊ธฐ ์œ„ํ•ด์„œ๋Š” redirect๋กœ๋Š” ์•ˆ ๋˜๊ณ , router.replace๋ฅผ ํ•ด์•ผ ํ•จ. "use client" ์‚ฌ์šฉ ํ•„์š”.

์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ๊ตฌ๋ถ„ํ•˜๊ธฐ

use client vs use server

๋‹ค์Œ ์—๋Ÿฌ๊ฐ€ ๋‚˜๋Š” ๋ถ€๋ถ„์€ ๋ถ„๋ฆฌํ•˜์ž(Client Component๋กœ ๋ถ„๋ฆฌ ํ›„ importํ•˜๋ฉด ๋จ)

Error: usePathname only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/react-client-hook-in-server-component   
at RootLayout (./src/app/layout.tsx:29:86)
at stringify (<anonymous>)
  • NavIcons๋กœ ์•„์ด์ฝ˜๋“ค ๋ถ„๋ฆฌ

  • _components ํด๋”์— ์ฃผ๋กœ Client Component ์ƒ์„ฑ

  • useState, useRef, useEffect, useContext, useRouter, useSearchParams, onClick ๋“ฑ๋“ฑ ๋งŽ๋‹ค

  • ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ๋„ ์„œ๋ฒ„์ชฝ์—์„œ ๋ Œ๋”๋ง ๋จ, ์ฆ‰ SSR ๋Œ€์ƒ

  • ์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ๋Š” ์„œ๋ฒ„"์—์„œ๋งŒ" ๋ Œ๋”๋ง ๋จ

compose/tweet ์ฒ˜๋ฆฌ

compose/tweet๋„ ์ด๊ฑธ๋กœ ์ฒ˜๋ฆฌ

  • @modal/compose/tweet์œผ๋กœ ๋ฐ”๊พธ๊ณ  parallel router ์ ์šฉ
  • @modal์ด๋ผ๋Š” slot ์‚ฌ์šฉํ•˜๋ฉด props.modal๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • parallel router ์ ์šฉ ์‹œ default.tsx ๊ผญ ๋„ฃ์–ด์ฃผ์–ด์•ผ ํ•จ!!! ์ƒˆ๋กœ๊ณ ์นจํ•  ๋•Œ ์ฃผ์˜ํ•  ๊ฒƒ!!!
  • ์ƒˆ๋กœ๊ณ ์นจ ์‹œ์—๋„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ๋Š” home์ด ๋ณด์—ฌ์•ผ ํ•จ
  • compose/tweet ํด๋” ํ•œ ๋ฒˆ ๋” ๋งŒ๋“ค์–ด์ฃผ๊ธฐ

(afterLogin)/home/@modal/(..)compose/tweet์€ ์•ˆ ๋˜๋‚˜์š”?

  • home ํด๋” ์•ˆ์— @modal์€ app/(afterLogin)/layout.tsx์—์„œ ์ธ์‹๋˜์ง€ ์•Š์•„์„œ ์‚ฌ์šฉ ๋ถˆ๊ฐ€
  • layout.tsx์™€ ๊ฐ™์€ ์œ„์น˜์ธ app/(afterLogin) ์•ˆ์— @modal์„ ๋„ฃ์–ด์•ผ ํ•จ

faker.js

  • faker.js๋Š” ๋”๋ฏธ๋ฐ์ดํ„ฐ ์ƒ์„ฑ์šฉ
  • npm i fakerํ•˜์ง€ ์•Š๋„๋ก ์ฃผ์˜
npm i -D @faker-js/faker
  • ์šฉ๋Ÿ‰์ด ํฌ๋ฏ€๋กœ ๋ฐฐํฌ ์‹œ์—๋Š” ์ œ๊ฑฐํ•ด์•ผ ์šฉ๋Ÿ‰์„ ์ค„์ผ ์ˆ˜ ์žˆ์Œ

์„œ๋ฒ„ ์ปดํฌ๋„ŒํŠธ์™€ ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ ๊ฐ™์ด ์“ฐ๊ธฐ

  • Client Component์—์„œ Server Component importํ•˜๋ฉด ์•ˆ ๋จ, importํ•˜๋ฉด Server Component๋„ Client Component์ฒ˜๋Ÿผ ์ทจ๊ธ‰๋จ
  • props(children์ด๋‚˜ ๊ธฐํƒ€ props)๋กœ ๋„˜๊ธธ ๊ฒƒ

๊ทธ๋Ÿฐ๋ฐ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๊ฐ€ API๋ฅผ ์•„์ง ๋ชป ๋งŒ๋“ค์—ˆ๋‹ค.

MSW@2

npm install msw -D
npx msw init public/ --save
  • ์‹ค์ œ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋กœ ๋ณด๋‚ด๋Š” ์š”์ฒญ์„ ๊ฐ€๋กœ์ฑŒ ์ˆ˜ ์žˆ์Œ
  • ํ”„๋ก ํŠธ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ž„์˜๋กœ ์‘๋‹ต์„ ๋งŒ๋“ค์–ด๋‚ผ ์ˆ˜ ์žˆ์Œ(์„ฑ๊ณต, 400, 500 ์—๋Ÿฌ ๋ชจ๋‘ ๊ฐ€๋Šฅ)

ํ•ด๋‹น ์ด์Šˆ๋กœ msw ์„œ๋ฒ„์—์„œ ์‚ฌ์šฉ ๋ถˆ๊ฐ€

  • ์œ„ ์ด์Šˆ ํ•ด๊ฒฐ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” http ์„œ๋ฒ„ ์ง์ ‘ ์ƒ์„ฑ

Server Actions

  • ํšŒ์›๊ฐ€์ž…์— ์ ์šฉํ•˜๊ธฐ(Next 14๋ถ€ํ„ฐ ๊ฐ€๋Šฅ)
  • ํด๋ผ์ด์–ธํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ๋„ server action ํ•จ์ˆ˜๋ฅผ import ํ•ด์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • ํผ ๊ฒ€์‚ฌ๋ฅผ ์œ„ํ•ด useFormState์™€ useFormStatus ์ ์šฉํ•˜๊ธฐ

next-auth@5

npm install next-auth@5 @auth/core
  • next-auth@5๊ฐ€ ์„ค์น˜๊ฐ€ ์•ˆ ๋˜๋ฉด next-auth@beta๋ฅผ ๋Œ€์‹  ์„ค์น˜
  • auth.ts, middleware.ts, app/api/auth/[...nextauth]/route.ts ์ƒ์„ฑ
  • ๋กœ๊ทธ์ธ์„ ์œ„ํ•ด signIn("credentials") ํ˜ธ์ถœ(csrf ํ† ํฐ ์•Œ์•„์„œ ๊ด€๋ฆฌ), 5.0.0-beta.4์—์„œ๋Š” ๋ฒ„๊ทธ ์žˆ์œผ๋‹ˆ ์ฃผ์˜!
  • ๋กœ๊ทธ์•„์›ƒ์„ ์œ„ํ•ด signOut ํ˜ธ์ถœ
  • ํด๋ผ์ด์–ธํŠธ์—์„œ ๋‚ด ์ •๋ณด ๊ฐ€์ ธ์˜ฌ ๋•Œ๋Š” useSession(), ์„œ๋ฒ„์—์„œ๋Š” await auth();
  • session ์•ˆ ๋‚ด ์ •๋ณด๋Š” email, name, image๋งŒ ๊ฐ€๋Šฅ(ํ—ท๊ฐˆ๋ฆฌ๋‹ˆ ์ฃผ์˜)

ํŽ˜์ด์ง€ ์ ‘๊ทผ ๊ถŒํ•œ

middleware.ts๋กœ ํŽ˜์ด์ง€ ์ ‘๊ทผ ์ œ์–ด

  • (afterLogin) ๋‚ด๋ถ€์˜ [username]๊ณผ [username]/status/[id] ํŽ˜์ด์ง€๋Š” ๋ชจ๋‘ ๊ณต๊ฐœ
  • ๊ทธ ์™ธ (afterLogin) ํŽ˜์ด์ง€๋“ค์€ ๋กœ๊ทธ์ธํ•œ ์‚ฌ๋žŒ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅ

React Query ๋„์ž…ํ•˜๊ธฐ

npm i @tanstack/react-query @tanstack/react-query-devtools
  • ํƒ€์ž… ์ž˜ ๋งž์ถ”๊ธฐ(QueryFunction, QueryKey)
  • ๋งํฌ
  • ์ฟผ๋ฆฌ ํ‚ค ์ •๋ฆฌ(๋Œ€๋ถ„๋ฅ˜-์ค‘๋ถ„๋ฅ˜-์†Œ๋ถ„๋ฅ˜)
  • SSR(HydrationBoundary, prefetchQuery)

์ธํ”ผ๋‹ˆํŠธ ์Šคํฌ๋กค๋ง

๋งํฌ

  • ์„œ๋ฒ„์‚ฌ์ด๋“œ์—์„œ๋„ prefetchInfiniteQuery๋กœ ๋ณ€๊ฒฝ
  • ์ปค์„œ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์ดํ•ด
npm install react-intersection-observer

๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋“œ๋””์–ด API ๋ฌธ์„œ๋ฅผ ์ฃผ์—ˆ๋‹ค

useMutation

๋งํฌ

Optimistic Update

๋งํฌ

์„œ๋ฒ„ ์ฟ ํ‚ค ๊ตฌ๋ถ„ํ•ด์„œ ๊ด€๋ฆฌ ํ•„์š”

  • connect.sid๋Š” ๋ฐฑ์—”๋“œ ์„œ๋ฒ„์šฉ ์ฟ ํ‚ค
  • authjs.session-token(๊ตฌ next-auth.session-token)์€ ํ”„๋ก ํŠธ ์„œ๋ฒ„์šฉ ์ฟ ํ‚ค
  • ์ฟ ํ‚ค๋ฅผ ์ „์†กํ•˜๋ ค๋ฉด credentials: 'include' ํ•„์š”
  • ํ”„๋ก ํŠธ ์„œ๋ฒ„์—์„œ ๋ฐฑ์—”๋“œ ์„œ๋ฒ„๋กœ ์ฟ ํ‚ค๋ฅผ ์ „์†กํ•˜๋ ค๋ฉด headers: { Cookie: cookies().toString() } ํ•„์š”

์บ์‹œ ์ „๋žต

๋งํฌ

์บ์‹œํ•  ๋ฐ์ดํ„ฐ ์ข…๋ฅ˜ ๊ตฌ๋ถ„ํ•˜๊ธฐ img.png

  • Request Memo(๋ Œ๋”๋ง ์‹œ GET Request ์‹œ ๊ฐ™์€ ์ฃผ์†Œ fetch๋ฉด ํ•œ ๋ฒˆ๋งŒ ์š”์ฒญํ•ด์„œ ๊ฐ€์ ธ์˜ด, route.js์—์„œ๋Š” ์•ˆ ๋จ) img_1.png img_2.png
  • Data Cache(ํ•œ ๋ฒˆ fetchํ•œ ๊ฒƒ์„ ์„œ๋ฒ„๊ฐ€ ๊ธฐ์–ตํ•ด๋‘๊ณ  ์žˆ๋‹ค๊ฐ€ ๋‹ค์Œ ์š”์ฒญ ๋•Œ ์žฌ์‚ฌ์šฉ) img_3.png img_4.png
  • Full Route Cache: ํŽ˜์ด์ง€ ์ „์ฒด๋ฅผ ์บ์‹ฑํ•˜๋Š” ๊ฒƒ(static page๋งŒ ๊ฐ€๋Šฅ, page router์˜ ISR์„ ๋Œ€์ฒด) img_5.png
  • Router Cache: ํด๋ผ์ด์–ธํŠธ์—์„œ layout, page๋ณ„๋กœ ๋”ฐ๋กœ ์บ์‹ฑํ•ด๋‘๋Š” ๊ฒƒ img_6.png
  • Static vs Dynamic rendering: Dynamic function์„ ์“ฐ๋Š”๊ฐ€ vs Cache๋ฅผ ์“ฐ๋Š”๊ฐ€
  • dynamic function์„ ์“ฐ์ง€ ์•Š๊ณ  cache๋ฅผ ํ™œ์šฉํ•˜๋ฉด static ํŽ˜์ด์ง€

๋นŒ๋“œ(SSG, ISR, Dynamic)

๋งํฌ

Zustand

"use client" ์•„๋ž˜์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

  • context api ๋Œ€๋น„ ์ตœ์ ํ™”๊ฐ€ ๊ธฐ๋ณธ ์ ์šฉ๋˜์–ด ์žˆ์–ด์„œ ์‹ ๊ฒฝ์“ธ ๊ฒŒ ์—†๋‹ค.
  • client component์—์„œ๋Š” async component ๋ถˆ๊ฐ€๋Šฅ
  • ๋„์ž… ํ›„ ์ƒˆ๋กœ๊ณ ์นจ ํ•œ ๋ฒˆ์”ฉ ํ•ด๋ณผ ๊ฒƒ

Vanilla Extract

npm i @vanilla-extract/css @vanilla-extract/next-plugin

next.config.js

const {
  createVanillaExtractPlugin
} = require('@vanilla-extract/next-plugin');
const withVanillaExtract = createVanillaExtractPlugin();
...
module.exports = withVanillaExtract(nextConfig);
  • app/globals.css๋ฅผ app/globalTheme.css.ts๋กœ ๋Œ€์ฒด
  • :root์— @media (prefers-color-scheme: dark)๋ฅผ ์ ์šฉํ•˜๋ ค๋ฉด ์กฐ๊ธˆ ๋ณต์žกํ•จ
  • (beforeLogin)/_component ๋‚ด๋ถ€ css.ts ํŒŒ์ผ๋“ค์ด VE ํŒŒ์ผ๋“ค์ž„
  • globalStyle ํ•จ์ˆ˜๋ฅผ ๋ณด๋ฉด ์•Œ๊ฒ ์ง€๋งŒ, nested selector๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋ญ”๊ฐ€ ๋ถ€์ž์—ฐ์Šค๋Ÿฌ์›€

๋ฐฐํฌํ•˜๊ธฐ

  • npm run build๋กœ ๊ฒฐ๊ณผ ํŒŒ์ผ ์ƒ์„ฑ
  • ๋นŒ๋“œ ์‹œ ์šฉ๋Ÿ‰ ์ž˜ ํ™•์ธํ•˜๊ธฐ
  • .env, .env.production ๊ฐ’ ์‹ค์ œ ์„œ๋ฒ„ ๊ฐ’์œผ๋กœ ์ˆ˜์ •ํ•˜๊ธฐ
  • ์„œ๋ฒ„์—์„œ npm run start๋กœ ์‹คํ–‰ํ•˜๋ฉด ๋จ

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published