์๋ ํ์ธ์ ํ๋ก ํธ์๋ ๊ฐ๋ฐ์ ์ฝ๋ฉ๋จน๋ฐฉ์ ๋๋ค.
์ ๋ ์ฝ 3๋ ๋์ ํ์ ์์ ๊ฐ๋ฐ์ ํ์๊ณ ํ์ฌ๋ ์๋ก์ด ๊ธฐ์ ๋ค์ ํ์ตํ๋ฉฐ
๊ฐ์ธ์ ์ผ๋ก ๊ฐ๋ฐ์ ์งํํ๊ณ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ ๋ ๊ทธ๋ฐ ๊ณผ์ ์์ ์ต๋ํ ๊ฒ๋ค์ ๊ณต์ ํ๊ณ ์ ํฉ๋๋ค.
๊ฐ์ฌํฉ๋๋ค.
Courses
Reviews
- Creating a Chat GPT based on Next.js App router
- Creating a Chat GPT based on Next.js App router
- Creating a Chat GPT based on Next.js App router
- Creating a Chat GPT based on Next.js App router
- Creating a Chat GPT based on Next.js App router
Posts
Q&A
์น์ 6 ํค๋ ๋งํฌ์ - zustand ์ ์ฉ์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค
zustand๊ฐ ํน์ ๋ฒ์ ๋ถํฐ๋ ํญ์ ๋ฐํ ๊ฐ์ฒด๊ฐ ์๋ก ๋ง๋ค์ด ์ง๋ฉด ๋ฆฌ๋ ๋๋ง์ด ๋๋๋ก ์์ ๋์๋๋ฐ์.useModelStore์์ ์๋ ํฐ ํจ์(state => ({ ... })๋ ๋งค๋ฒ ์๋ก์ด ๊ฐ์ฒด๋ฅผ ๋ฐํ ํ๊ธฐ ๋๋ฌธ์ ๋ด์ฉ์ด ๊ฐ์๋ ์๋ก์ด ์ฐธ์กฐ๊ฐ ์์ฑ๋์ด ์ด์ ๊ณผ ๋ค๋ฅด๋ค๊ณ ํ๋จํด ๋ฌดํ ๋ฆฌ๋ ๋๋ง์ด ์ผ์ด๋๊ฒ ๋ฉ๋๋ค.๋ฐ๋ผ์ ์๋ ์ฒ๋ผ ๊ฐ๊ฐ ๊ฐ์ ธ์ค์๊ฑฐ๋ ๋งจ์๋ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด์ useShallow ๋ฅผ ์ฌ์ฉํด๋ณด์๋ฉด ํด๊ฒฐ๋ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค!const model = useModelStore(state => state.model);const updateModel = useModelStore(state => state.updateModel); https://zustand.docs.pmnd.rs/guides/prevent-rerenders-with-use-shallow
- 0
- 2
- 40
Q&A
page loading... ์ด ์๋ณด์ ๋๋ค.
๋จผ์ loading์ด ์๋ณด์ด๋ ๊ฐ์ฅ ์ ๋ ฅํ ์ด์ ๋ ์บ์์ธ๋ฐ์.์ ์์์ผ๋ก๋ Reqeust Memoization์ผ๋ก fetch๋ ๊ฐ์ ์์ฒญ์ ๋ค์ ๋ง๋๋ฉด ๋ฉ๋ชจ๋ฆฌ์์ ๊ฒฐ๊ณผ๋ฅผ ์ฆ์ ๋ฐํํ๊ฒ ๋ผ์ ํน์๋ ์ด์ ์ ํธ์ถ์ด ๋์๋ค๋ฉด ๋ก๋ฉ์ด ์๋ณด์ด๊ณ ๋ฐ๋ก ๋ ๋๋ง ๋ ์ ์์ต๋๋ค. ๊ทธ ์ธ์๋ ์๋ ์ฌ์ง ์ฒ๋ผ next.js๋ ์ฌ๋ฌ๊ฐ์ง์ ์บ์๋ฅผ ์ง์ํ๊ณ ์์ผ๋ ๊ณต์๋ฌธ์๋ฅผ ํ๋ฒ ํ์ธํด๋ณด์๋ฉด ์ข ๋ ๋์์ด ๋์ค ๊ฑฐ ๊ฐ์ต๋๋ค :)(์ฌ์ง).๊ณต์๋ฌธ์: https://nextjs.org/docs/app/guides/caching
- 0
- 2
- 34
Q&A
Streaming ๊ด๋ จ ์ง๋ฌธ
์๋ ํ์ธ์~ page loading ๋ก๋ฉ ์ดํ์ ๋ก๋ฉ์ด ์๋ณด์ด๋ ์ด์ ๋ ์๋ ๊ณต์๋ฌธ์์์ ํ์ธํ ์ ์๋๋ฐ์!nextjs์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก request memoization ํ๊ธฐ ๋๋ฌธ์ ๋์ผํ ์์ฒญ์ ๋ํด์๋ ์บ์๋ฅผ ํด์ DashboardPage์์ ํธ์ถํ ์ดํ Card์์ ํธ์ถํ ๋๋ ์บ์๊ฐ ๋์ด ๋ฐ๋ก ๋ณด์ฌ์ง๋๊ฒ์ผ๋ก ์๊ฐ์ด๋ฉ๋๋ค! ์ค์ ๋ก ์ ๊ฐ ์ฝ๋ ๋ฐ์์ ๋์๋ณด๋์ชฝ์ ์ฃผ์์ ํ๊ณ ๋์ ํ ์คํธ๋ฅผ ํด๋ณด์์ ๋๋ ์ ๋์ค๋ ๊ฒ์ผ๋ก ํ์ธํ์ต๋๋ค!(์ฌ์ง)(์ฌ์ง)
- 0
- 2
- 67
Q&A
loading์ด ๋์ํ์ง ์์ต๋๋ค.
/dashboard ์ ์๋ loading.tsx ๋ง์ํ์ ๊ฑฐ ๋ง๋์? ์ ๊ฐ ์๊ฐ์๋์ด ์ฃผ์ github ์์ clone ํด์ ํ ์คํธ ํด๋ณด์์ ๋ ์๋์ฒ๋ผ ์ ๋์ค๋๊ฑธ ํ์ธํ์ต๋๋ค ๐ ํน์ /dashboard ์์ ํ์ธํ๊ฒ ๋ง์ผ์ ์ง ํน์ ์ฒซ ๋ก๋ฉ์ดํ์ ์บ์๋ก ์ ๋ณด์ผ ์ ์์ผ๋ ํ ์คํธ ํ์ค ๋ ๊ฐ๋ ฅ ์๋ก๊ณ ์นจ์ผ๋ก ํ ์คํธ ํด๋ณด์๋ฉด ๋ ๊ฑฐ ๊ฐ์ต๋๋ค(์ฌ์ง)
- 0
- 2
- 168
Q&A
Runtime Error
signup.ts ๋ ์๋ฒ ์ก์ ์ด๊ธฐ ๋๋ฌธ์ 'use client' ๊ฐ ์๋๋ผ 'use server'๋ฅผ ์์ฑํด์ฃผ์ ์ผ ํฉ๋๋ค!์ถ๊ฐ์ ์ผ๋ก ์๋ฌ๊ฐ ๋๋ ์ด์ ์ ๋ํด ์ข ๋ ์ค๋ช ๋๋ฆฌ๋ฉดdb.insert(user).values({name, email, password: hasehdPassword});์์ ๊ฐ์ด db ๋ฅผ ์ฌ์ฉํ ๋ ๋ฐ์ดํฐ ๋ฒ ์ด์ค์ ์ ๊ทผํด์ผํ๊ธฐ ๋๋ฌธ์ DATABASE_URL ์ด ํ์ํ๊ฒ ๋ฉ๋๋ค.๊ทธ๋ฆฌ๊ณ Next.js ์์๋ ํด๋ผ์ด์ธํธ์์ ํ๊ฒฝ ๋ณ์์ ์ ๊ทผํ ๋, "NEXT_PUBLIC_" ์ ์์ ๋ถ์ฌ์ค์ผ ๊ฐ์ ธ์ฌ ์ ์๋๋ฐ์. DATABASE_URL ์ ๊ฒฝ์ฐ ๋ฐ์ดํฐ ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ์ํ ํ๊ฒฝ๋ณ์์ด๊ธฐ ๋๋ฌธ์ ์๋ฒ์์๋ง ์ฌ์ฉํ๊ธฐ ์ํด NEXT_PUBLIC์ ๋ถ์ด์ง ์์๊ณ ๊ทธ๋ ๊ธฐ์ ํ์ฌ 'use client'๋ผ๊ณ ์ ์ธ๋์ด ์๋ ํ์ผ์์ ํ๊ฒฝ ๋ณ์๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ด ์๋ฌ๊ฐ ๋๋ ๊ฒ์ ๋๋ค. ์์ผ๋ก ๋์ผํ ์๋ฌ๊ฐ ๋ฐ์ํ ๋์ DATABASE_URL ์ ๋ฌธ์ ๊ฐ ์๋ค๋ฉด ํด๋ผ์ด์ธํธ์์ ์๋ฒ์์๋ง ์ ๊ทผํ ์ ์๋ ํ๊ฒฝ ๋ณ์์ ์ ๊ทผํ์ง ์์๋์ง(ex: db ๋ฅผ ์กฐ์ํ๋ ์ฝ๋) 1์ฐจ์ ์ผ๋ก ์์ฌ ํด๋ณด์๊ธธ ์ถ์ฒ ๋๋ฆฝ๋๋ค.์ฐธ๊ณ : https://nextjs.org/docs/app/building-your-application/configuring/environment-variables
- 0
- 2
- 127
Q&A
Route Handler ์์ Post ์ฝ๋ ์์ฑํด๋ดค๋๋ฐ ๊ณ์ ์๋ฌ๊ฐ ๋ฉ๋๋ค ใ ใ
์๋ AI ๋๊ธ์ ๋ต๋ณ์ ๋ฌ์๋ค์ ใ ใ ๋ค์ ๋ต๋ณ์ ๋ฌ๊ฒ ์ต๋๋ค!์๋ ํ์ธ์!์๋ง ์ด๋ฒ์ nextjs ๋ฅผ ์ค์นํ๊ณ ๋ฐ๋ผ์ค์ จ๋ค๋ฉด 15 ๋ฒ์ ์ด ์ค์น๋์ จ์๊ฑฐ์์!15๋ฒ์ ๋ถํฐ๋ params ๊ฐ async ๋ก ๋ฐ๋์ด์ ํด๋น ๋ถ๋ถ์ ๋ํ ์ฒ๋ฆฌ๋ฅผ ํ์ ์ผํฉ๋๋ค!์์์์ ์ ์ด ๋๊ธด ํ๋๋ฐ ๋ค์ ํ๋ฒ ์๋ดํด๋๋ฆด๊ฒ์!!์๋์ ๊ฐ์ด ์์ ํ์๋ฉด ์ ๋์ค๊ฒ๋๋คroute.tsimport { NextResponse } from "next/server"; // params ๋ async ์ด๊ธฐ ๋๋ฌธ์ Promise ๋ก ๊ฐ์ธ์ ํ์ดํ type Params = Promise; export async function POST(request: Request, segmentData: { params: Params }) { const userData = await request.json(); // params์ ์ฌ์ฉํ ๋ ์ญ์ await๋ฅผ ๋ถ์ฌ์ฃผ์๋ฉด ๋ฉ๋๋ค. const params = await segmentData.params; console.log("server user data", userData); console.log("server params", params.testId); return NextResponse.json( { message: "์ฑ๊ณต์ ์ผ๋ก ์์ฑํ์์ต๋๋ค." }, { status: 201 } ); } page.tsximport { use } from "react"; // page ์ญ์๋ params ๋ถ๋ถ์ Promise๋ก ๊ฐ์ธ์ค๋๋ค. type Params = Promise; export default function TestDetailPage(props: { params: Params }) { // client page ์์๋ await๋ฅผ ์ฌ์ฉํ ์ ์์ผ๋ฏ๋ก react์์ ์๋ก ์ถ๊ฐ๋ use hook์ผ๋ก ๋ฐ์์ฃผ์๋ฉด ๋ฉ๋๋ค. const { testId } = use(props.params); const handleSubmit = async () => { const response = await fetch("/api/test/1234", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ name: "test name", email: "test email" }), }); const data = await response.json(); console.log("client data", data); }; return ( ํ ์คํธ ๋ํ ์ผ ํ์ด์ง: {testId} ์ ์ก ); } ๋ฐ๋ ๋ถ๋ถ์ ๋ํด์๋ ์๋ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด์ฃผ์ธ์!https://nextjs.org/docs/app/building-your-application/upgrading/version-15#asynchronous-page
- 0
- 2
- 179
Q&A
์น์ 7 ์ฌ์ด๋๋ฐ &๋ํํ์ด์ง ์ฐ๋ 9๋ถ50์ด๊ฒฝ ์ง๋ฌธ
(์ฌ์ง) revalidatePath ์ ๋ํด ๊ณต์๋ฌธ์๋ฅผ ๋ณด๋ฉด ์ ์ฌ์ง ์ฒ๋ผ revaliatePath() ์์ ๋ค์ด๊ฐ๋ path ๋ url path ๊ฐ ์๋๋ผ filesystem path ๋ฅผ ๋ฃ๋๊ฑธ ๋ณผ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ host ๋ ๋ฌด๊ดํ๋ฉฐ app(root) ๋ถํฐ ํ์ filesystem, route segment ์ ๋ง๊ฒ path๋ฅผ ๋ฃ์ด์ฃผ์๋ฉด ๋ฉ๋๋ค.
- 0
- 1
- 131
Q&A
์น์ 7 ์ฌ์ด๋๋ฐ &๋ํํ์ด์ง ์ฐ๋ 3๋ถ50์ด๊ฒฝ ์ง๋ฌธ
์๋ ํ์ธ์! ์ง๋ฌธ ์ฃผ์ ๋ด์ฉ์ ๋ต๋ณ์ ํ๊ธฐ ์ํด์ ๋จผ์ next.js ์์ ๋ ๋๋ง์ด ์ด๋ค ๊ณผ์ ์ ํตํด ์ด๋ฃจ์ด์ง๋์ง๋ฅผ ๋จผ์ ์ค๋ช ๋๋ ค์ผํ ๊ฑฐ ๊ฐ์ต๋๋ค. nextjs ์์ ์๋ฒ์์ 2๋จ๊ณ ํด๋ผ์ด์ธํธ์์ 3๋จ๊ณ์ ๊ฑธ์ณ ๋ ๋๋ง์ด ์ผ์ด๋๊ฒ ๋๋๋ฐ์. ๊ทธ ๊ณผ์ ์ ์๋์ ๊ฐ์ต๋๋ค.์๋ฒ๋ฆฌ์กํธ๋ ์๋ฒ ์ปดํฌ๋ํธ๋ฅผ react server component payload(RSC Payload) ์ ํํ๋ก ๋จผ์ ๋ ๋๋งํ๊ฒ ๋ฉ๋๋ค.RSC Payload ๋ ์์ถ๋ ๋ฐ์ด๋๋ฆฌ ํํ์ผ๋ก ์๋์ ๊ฐ์ ์ ๋ณด๋ฅผ ํฌํจํ๊ณ ์์ต๋๋ค.์๋ฒ ์ปดํฌ๋ํธ ๋ ๋๋ง ๊ฒฐ๊ณผ๋ฌผํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋ ์์น์ ํด๋น ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ํ placeholder์๋ฒ ์ปดํฌ๋ํธ์์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ก ์ ๋ฌ๋ ๋ชจ๋ ์ํ๊ทธ๋ฆฌ๊ณ ์ด rsc payload ์ javascript instructions ์ ์ฌ์ฉํด ์๋ฒ์์ ์ด๊ธฐ html ์์ฑํด ํด๋ผ์ด์ธํธ์ ๋ณด๋ ๋๋ค.ํด๋ผ์ด์ธํธํด๋ผ์ด์ธํธ๋ ์ด๊ธฐ html ๋ฅผ ์ฆ์ ํ์ํ๊ณ ์ด ์ด๊ธฐ html ์ non-interactive ํ๊ณ ์ด๊ธฐ ๋ก๋์๋ง ์ฌ์ฉ๋ฉ๋๋ค.ํด๋ผ์ด์ธํธ์์ rsc payload ๋ฅผ ์ฌ์ฉํด ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ฅผ ์ฑ์๋ฃ๊ณ (reconcile) dom์ ์ ๋ฐ์ดํธ ํฉ๋๋ค.์๋ฒ์์ ๋ฐ์ javascript instructions ์ ์ฌ์ฉํด ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ์ hydrate ํฉ๋๋ค. ์์ ๊ฐ์ ๋ ๋๋ง ๊ณผ์ ์ ๊ฑฐ์น๋๋ฐ์. ๊ณผ์ ์ ๋ณด๋ฉด ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ ์๋ฒ์์ "ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๊ฐ ๋ ๋๋ง๋ ์์น์ ํด๋น ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ํ placeholder" ์ ์ ๋ณด๋ง ๊ฐ์ง๊ณ ์๊ธฐ ๋๋ฌธ์ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ ๋ด๋ถ๊ฐ ์ด๋ป๊ฒ ๊ตฌํ๋์ด ์๋์ง, ์ด๋ป๊ฒ ๋ ๋๋ง์ด ๋๋ ์ง ์๋ฒ์์๋ ์์ง ๋ชปํฉ๋๋ค. ๋ฐ๋ผ์ ๊ทธ ํ์์ ์๋ ์ปดํฌ๋ํธ ์ญ์๋ ์์ฐ์ค๋ฝ๊ฒ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ๋ก ์ฒ๋ฆฌํ๊ฒ๋ฉ๋๋ค. ํ์ง๋ง props๋ก ๋ฐ์ ์๋ฒ ์ปดํฌ๋ํธ๋ ์์(์๋ฒ์ปดํฌ๋ํธ)์์ ๋ฐ๊ธฐ ๋๋ฌธ์ ์ด๋ฏธ ๋ ๋๋ง๋ ๊ฒฐ๊ณผ๊ฐ props๋ก ๋ค์ด์ค๊ฒ ๋๊ณ rsc payload์๋ ์ด props ์ ๋ณด๋ ์๊ธฐ ๋๋ฌธ์ ์๋ฒ ์ปดํฌ๋ํธ๋ฅผ ์ ์งํ๋ฉด์ ๋ฐ์ ์ ์๊ฒ ๋ฉ๋๋ค. ์๋ ์ฝ๋๋ฅผ ๋ณด๋ฉด ์ข ๋ ์ดํดํ์๊ธฐ ์ฌ์ธ ๊ฑฐ ๊ฐ์์.export default function ClientComponent({ children, }: { children: React.ReactNode }) { const [count, setCount] = useState(0) return ( setCount(count + 1)}>{count} {children} )} import ClientComponent from './client-component' import ServerComponent from './server-component' // Pages in Next.js are Server Components by default export default function Page() { return ( // ์ด๋ ๊ฒ children ์ผ๋ก ๋ค์ด์ค๋ ์ปดํฌ๋ํธ๋ ์์ ์๋ฒ ์ปดํฌ๋ํธ์์ ๋ ๋๋ง์ ๋ง์น ํ // props ๋ก ๋ค์ด์ค๊ธฐ ๋๋ฌธ์ ์๋ฒ ์ปดํฌ๋ํธ๋ก ์ ์งํ ์ ์์ต๋๋ค. )} ์ฐธ๊ณ : https://nextjs.org/docs/app/building-your-application/rendering/server-components#how-are-server-components-renderedhttps://nextjs.org/docs/app/building-your-application/rendering/composition-patterns#unsupported-pattern-importing-server-components-into-client-components
- 0
- 1
- 122