- ํ๋ก ํธ ๊ฐ๋ฐ์๋ก ๋ค์นด๋ผ์ฟ ๋ฐฐ ์ค ํ๋์ IT์๋น์ค ๊ธฐ์ ์ ์ฌ์งํ๊ณ ์์ต๋๋ค. ๐ 
- ๐ SW๋ง์์คํธ๋ก Expert ์ทจ์ ๋ฉํ ๋ง 
- ๐ Naver Boostcamp BE ๋ฉํ ๊ฒฝํ 
- ๐ FE 7Code ๋ก๋๋งต ๊ฐ์ ์ ์ 
Courses
Reviews
- Getting Started with Supabase and Next Full Stack (feat. Supabase OAuth, Next.js 14)
- Chat GPT Clone in 1 Hour with Cursor (One-Day Class)
- Developing AI Memoir Service with React + GPT API (One-Day Class)
- Developing AI Memoir Service with React + GPT API (One-Day Class)
- Chat GPT Clone in 1 Hour with Cursor (One-Day Class)
Posts
- Q&A - DBeaver์ supabase connection - ์๋ ํ์ธ์. Session pooler ๋ฐฉ์์ผ๋ก ์ปค๋ฅ์  ํด๋ณด์ธ์.! (์ฌ์ง) Supabase์์ ์ ๊ณตํ๋ 3๊ฐ์ง ์ฐ๊ฒฐ ๋ฐฉ์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ๊ด๋ฆฌํ๋ ๋ฐฉ๋ฒ๊ณผ ์ฐ๊ฒฐ ์ ์ง ์๊ฐ์ ๋ฐ๋ผ ์ฃผ์ํ ์ฐจ์ด์ ์ด ์์ต๋๋ค. ์ฐ๊ฒฐ ๋ฐฉ์๋ณ ์์ธ ์ค๋ช 1. Direct Connection (์ง์  ์ฐ๊ฒฐ) ๊ฐ์ฅ ์ ํต์ ์ธ ๋ฐฉ์์ ๋๋ค. ํด๋ผ์ด์ธํธ(DBeaver)๊ฐ Supabase PostgreSQL ์ธ์คํด์ค์ ์ง์  ์ฐ๊ฒฐํ์ฌ ํ๋์ ์ ์ฉ ์ฐ๊ฒฐ์ ์ค๋ซ๋์ ์ฌ์ฉํฉ๋๋ค.์ฅ์ : ๋ชจ๋ PostgreSQL ๊ธฐ๋ฅ์ ์๋ฒฝํ๊ฒ ์ง์ํ๋ฉฐ, ์ธ์  ๊ธฐ๋ฐ ์ค์ (SET ๋ช ๋ น์ด ๋ฑ)์ ์ ์งํ๋ ๋ฐ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. DBeaver์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ํ์ํ๊ณ ๊ด๋ฆฌํ๋ ๋ฐ ๊ฐ์ฅ ์ต์ํ๊ณ ์์ ์ ์ธ ๋ฐฉ์์ ๋๋ค.๋จ์ : ๋ฐ์ดํฐ๋ฒ ์ด์ค๊ฐ ์์ฉํ ์ ์๋ **์ต๋ ์ฐ๊ฒฐ ์(max_connections)**๊ฐ ์ ํ์ ์ด๊ธฐ ๋๋ฌธ์, ๋ง์ ์์ ๋์ ์ฌ์ฉ์ ์์ฒญ์ด ๋ฐ์ํ๋ฉด ์ฐ๊ฒฐ ์ ํ์ ์ฝ๊ฒ ๋๋ฌํ ์ ์์ต๋๋ค.์ฐธ๊ณ : Supabase์์ Direct Connection์ ๊ธฐ๋ณธ์ ์ผ๋ก IPv6๋ฅผ ๊ถ์ฅํฉ๋๋ค. 2. Session Pooler (์ธ์  ํ๋ฌ) ์ฐ๊ฒฐ ํ๋ง(Connection Pooling) ๊ธฐ์ ์ ์ฌ์ฉํ์ง๋ง, ๋์ ๋ฐฉ์์ Direct Connection๊ณผ ์ ์ฌํฉ๋๋ค.ํด๋ผ์ด์ธํธ๊ฐ ์ ์ํ๋ฉด ํ๋ฌ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ํ ๋นํ๊ณ ํด๋ผ์ด์ธํธ๊ฐ ๋์ ๋๊น์ง ์ ์งํฉ๋๋ค. ์ฆ, ์ฌ๋ฌ ํด๋ผ์ด์ธํธ๊ฐ ์ง์  ์ฐ๊ฒฐ ์ ์ ํ์ ์ด๊ณผํ์ง ์๋๋ก ํ(Queue)์ ์ฐ๊ฒฐ ๊ณต์ ๊ธฐ๋ฅ์ ์ ๊ณตํ์ง๋ง, ์ฐ๊ฒฐ์ '์ค๋' ์ ์งํ๋ค๋ ์ ์ Direct Connection๊ณผ ๊ฐ์ต๋๋ค.์ฅ์ : Direct Connection์ ๋์์ผ๋ก ์ ํฉํ๋ฉฐ, ํนํ IPv4 ํ๊ฒฝ์์ ์ฌ์ฉํ๊ธฐ ์ข์ต๋๋ค. DBeaver์ ๊ฐ์ด ์ธ์  ์ํ ์ ์ง๊ฐ ํ์ํ GUI ๋๊ตฌ์ ๋งค์ฐ ์ ํฉํฉ๋๋ค.๋จ์ : Direct Connection์ฒ๋ผ ์ฐ๊ฒฐ์ ์ค๋ ์ ์งํ๋ฏ๋ก, ์๋ฒ๋ฆฌ์ค ํ๊ฒฝ๊ณผ ๊ฐ์ด ์ฐ๊ฒฐ ์์ฑ ๋ฐ ํด์ ๊ฐ ์ฆ์ ํ๊ฒฝ์์๋ ๋นํจ์จ์ ์ผ ์ ์์ต๋๋ค. 3. Transaction Pooler (ํธ๋์ญ์  ํ๋ฌ) ์ฐ๊ฒฐ ํ๋ง์ ์ฅ์ ์ ๊ทน๋ํํ ๋ฐฉ์์ผ๋ก, ๊ฐ์ฅ ๋์ ํ์ฅ์ฑ์ ์ ๊ณตํฉ๋๋ค.ํด๋ผ์ด์ธํธ๊ฐ SQL ์ฟผ๋ฆฌ๋ฅผ ์คํํ ๋ ํ์ํ ํธ๋์ญ์ ์ด ์งํ๋๋ ๋์์๋ง ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ์ ํ ๋นํ๊ณ , ํธ๋์ญ์ ์ด ์๋ฃ๋๋ ์ฆ์ ์ฐ๊ฒฐ์ ํ์ ๋ฐํํ์ฌ ๋ค๋ฅธ ํด๋ผ์ด์ธํธ๊ฐ ์ฆ์ ์ฌ์ฌ์ฉํ ์ ์๋๋ก ํฉ๋๋ค.์ฅ์ : ์ ์ ์์ ์ค์  ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ๋ก ์๋ฐฑ ๋ฐฐ ์ด์์ ํด๋ผ์ด์ธํธ ๋์ ์ ์์ ์ฒ๋ฆฌํ ์ ์์ด, ์๋ฒ๋ฆฌ์ค ํ๊ฒฝ(Edge/Serverless Functions)์ฒ๋ผ ์งง๊ณ ํญ๋ฐ์ ์ธ ์ฐ๊ฒฐ์ด ํ์ํ ๊ฒฝ์ฐ์ ์ต์ ์ ๋๋ค.๋จ์ : ํธ๋์ญ์  ๋จ์๋ก ์ฐ๊ฒฐ์ด ๋์ด์ง๊ณ ์ฌ์ฌ์ฉ๋๋ฏ๋ก, **์ธ์  ๊ธฐ๋ฐ ์ํ(Session-level state)**๋ฅผ ์ ์งํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ DBeaver์ ๊ฐ์ GUI ํด์์ ์ฌ์ฉํ๊ธฐ์๋ ๋ถํธํ ์ ์์ต๋๋ค. (์: PREPARE STATEMENT ์ฌ์ฉ ๋ถ๊ฐ) - 0
- 2
- 32
 
- Q&A - ๊ฐ์ํ๊ฒฝ ๊ฐ์๊ฑด ์๋์? - nvm ๊ฐ์ ๋๊ตฌ๋ก node.js ๋ฒ์  ์์ค์ ๊ด๋ฆฌ๋ ํฉ๋๋ค.! - 0
- 3
- 27
 
- Q&A - ๊ฐ์ํ๊ฒฝ ๊ฐ์๊ฑด ์๋์? - ์๋ ํ์ธ์. node.js ์ง์์๋ ๊ฐ์ํ๊ฒฝ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.ํ์ง๋ง ๋ณดํต ํ์ด์ฌ ์ฒ๋ผ ๊ฐ์ํ๊ฒฝ์ ๋๊ณ ์ฌ์ฉํ์ง๋ ์์์. ์๋ํ๋ฉด ๋ก์ปฌ ํ๋ก์ ํธ์ ๋ง๋ค node_modules ๊ฐ ํ๋์ฉ ์๊ฒจ์. ์ด๋ป๊ฒ ๋ณด๋ฉด ํ์ด์ฌ ๊ฐ์ํ๊ฒฝ์ด ๋ง๋ค์ด ์ง๋ ๊ฑฐ์ฃ . - 0
- 3
- 27
 
- Q&A - isLoading ๊ฐ์ด ๋ฐ๋๋ ์์ (๋์ ์์)์ด ๊ถ๊ธํฉ๋๋ค. - isLoading์ด useState๋ก ์ ์ธํ ๋ณ์๊ฐ ์๋๋ฐ๋ ๋ก๋ฉ ์ปดํฌ๋ํธ์์ ๋ฒํผ์ผ๋ก ๋ค์ ๊ทธ๋ ค์ฃผ๋์?https://github.com/dodokyo/yt-music-clone/blob/main/app/playlist/page.tsx๋ก๋ฉ ๋ณ์๊ฐ ์๋๋ฐ ๋ก๋ฉ ์ปดํฌ๋ํธ๊ฐ ๊ทธ๋ ค์ง๋ ๊ฒฝ์ฐ๋ ์ page.tsx๊ฐ ๋ก๋ฉ ๋๋ ๋์ loading.tsx๊ฐ ๋ ๋๋ง ๋๋ ๊ฒฝ์ฐ ์ ๋๋ค.page.tsx ๋ await๋ก ์ค๊ฐ์ ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌ ๋๋ ๋ถ๋ถ์ด ์์ต๋๋ค. " const playlist = await getPlaylistById(Number(props.searchParams.list));" ์ด ๋ถ๋ถ์ด์ฃ .์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ๋น ๋ฅด๊ฒ ์ฒ๋ฆฌ๋๊ธด ํ์ง๋ง, ๊ทธ ๋์ ํ์ด์ง๊ฐ ๋ณด์ฌ์ฃผ์ด์ผ ํ๋ ์ปดํฌ๋ํธ๋ loading.tsx๋ผ๊ณ ์ฝ์ํ๊ฒ์ด next.js ์ ๋๋ค. ๋ด๋ถ์ ์ธ ๋์์๋ฆฌ๋ React suspense ๋ผ๊ณ ๊ฐ์์์ ์ ๋ฌ๋๋ฆฐ๋ฐ ์์ต๋๋ค. ~ ๋ต๋ณ ๋๋ฆฌ๊ณ ๋๋ ์ง๋ฌธ์ ์ ํํ ์๋๋ฅผ ์ ๋ชจ๋ฅด๊ฒ ์ด์ ๋ค์ ๋จ๊ฒจ์ฃผ์๋ฉด ๋ ์ ํํ ๋ต๋ณ ๊ฐ๋ฅํฉ๋๋ค. - 0
- 3
- 44
 
- Q&A - 4.6๊ฐ ์ด๊ธฐ ๋ก๋ฉ ์๋ ์ผ์ด์ค ๋น๊ต - ๊ฐ์ ์ค๋ฅ ๋ถ๋ถ ์ฃ์กํฉ๋๋ค. ๊ฒฐ๋ก ์ ์ผ๋ก ์๋ ์ผ์ด์ค 1,2,3 ์ผ๋ก ๋ด์ฃผ์๋ฉด ๋ฉ๋๋ค. ์ฌ์ฉ์์ ์ ์ฅ์์ ์ฒซ ํ์ด์ง๋ฅผ ๋ณด๋๋ฐ ๊ณผ์ฐ ์ผ๋ง๋ ์๊ฐ์ด ๊ฑธ๋ฆฌ๋์ง ํ ์คํธ ํด๋ณด๋ ์ํฉ์ ๋๋ค.ํด๋น ์ผ์ด์ค๋ฅผ ๋๋๋๋ฐ Root Layout ๊ณผ ๊ทธ ์ธ Page Layout์ ๋ก๋ฉ ํ์์ ๊ตฌ๋ถํด์ ์๊ฐ ํ ์ฒซ ํ์ด์ง๊ฐ ์ผ๋ง ํ ๋ณด์ฌ์ง๋์ง ์๊ฐํ๋ฉด ๋ฉ๋๋ค. Case1 - Root Page Loading 4s + Home Page Loading 2s=> ์ฒซ ํ์ด์ง๋ฅผ ๋ณด๋๋ฐ 4์ด๊ฐ ๊ฑธ๋ฆฝ๋๋ค.Case2 - Root Page Loading 2s + Home Page Loading 4s=> ์ฒซ ํ์ด์ง๋ฅผ ๋ณด๋๋ฐ 2์ด๊ฐ ๊ฑธ๋ฆฝ๋๋ค. ๊ทธ๋ฌ๋ Home Page๋ ์ฌ์ ํ ๋ก๋ฉ ์ค ์ ๋๋ค. Case3 - Root Page Loading 2s + Home Page Loading 2s=> ์ฒซ ํ์ด์ง๋ฅผ ๋ณด๋๋ฐ 2์ด๊ฐ ๊ฑธ๋ฆฝ๋๋ค. ๊ทธ ์ฆ์ Home Page ๋ ๋ฐ๋ก ๋ณด์ ๋๋ค. - 0
- 2
- 54
 
- Q&A - Sidebar & Header ์ปดํฌ๋ํธ ๋ฑ ๋ ์ด์์ ์ค์  ๋ฐฉ์ - ์๋ฉํฑ ํ๊ทธ๋ฅผ ์ ์ฉ์ํค๋ฉด ์๋์ฒ๋ผ ์์ฑํด๋ ์ข์ต๋๋ค. {children} - 0
- 3
- 53
 
- Q&A - Sidebar & Header ์ปดํฌ๋ํธ ๋ฑ ๋ ์ด์์ ์ค์  ๋ฐฉ์ - ์๋ ํ์ธ์. ~ ๋์ค์ RootLayout์ Player๊ฐ ํ๋ ์ถ๊ฐ ๋ฉ๋๋ค. {children} ๋์ค์ (Site) ๋ฃจํธ ํ์ด์ง๋ ๋ค์ ๋ชจ์ต์ด๊ตฌ์. import React from "react"; import Category from "./components/Category"; import PagePadding from "@/components/PagePadding"; import PlayListCarousel from "@/components/PlayListCarousel"; import { dummyPlaylistArray, getPlaylistById } from "@/lib/dummyData"; import UserIcon from "@/components/UserIcon"; const page = async () => { const dummyPlaylistArray1 = [...dummyPlaylistArray]; const dummyPlaylistArray2 = [await getPlaylistById(1)]; const dummyPlaylistArray3 = [await getPlaylistById(2)]; const dummyPlaylistArray4 = [await getPlaylistById(3)]; return ( } title="๋ค์ ๋ฃ๊ธฐ" subTitle="๋๋" /> ); }; export default page; RootLayout์ ์๋์ฒ๋ผ ํด์ฃผ์ ๋ ์๊ด์์ต๋๋ค.๋จ, ๋ชจ๋ Layout์์ ์ฌ์ฉํ๋ Root Layout ์ด๋ฏ๋ก ๋ฐ์ดํฐ ํจ์นญ์ ์ต์ํ ํ์ฌ ๋น ๋ฅธ ๋ก๋ฉ์ ํ๋๋ก, ์ต๋ํ ๊ฐ๊ฒฐํ๊ฒ ์์ฑํ๋๊ฒ ์ข์ต๋๋ค. ~ {children} - 0
- 3
- 53
 
- Q&A - useCallback์ ๋ํ๋์ ๋ฐฐ์ด์ supabase ๋ฃ๋ ์ด์ ? - ์ง๋ฌธ์ ์๋๋ ์๋์ฒ๋ผ ํจ์ ์ธ์๋ก userId๋ฅผ ์ ๋ฌํ๋ ๊ฒฝ์ฐ ์ธ๊ฐ์? ๊ฐ๋ฅ ํฉ๋๋ค๋ง supabase auth๋ฅผ ์ด์ฉํ์ง๋ ๋ชปํฉ๋๋ค.const getUserInfo = useCallback(async (userId) => { const result = await supabase.(profile db ๋ฑ).getUserById(userId); if (result?.data?.user) setUser(result?.data?.user); }, [supabase]);const getUserInfo = useCallback(async () => { const result = await supabase.auth.getUser(); if (result?.data?.user) setUser(result?.data?.user); }, [supabase, userId]);์ ์ฒ๋ผ userId๊ฐ ์์กด์ฑ ๋ฐฐ์ด์ ๋ค์ด๊ฐ๋ ์๋ฏธ๋ ์์ต๋๋ค.์ง๋ฌธ์ ์๋๋ฅผ ์ ๋ชจ๋ฅด๊ฒ ๋ค์. ใ ใ ์์กด์ฑ ๋ฐฐ์ด์ ํน์  ๋ณ์๊ฐ ๋ฐ๋๋๊ฒ์ ์บ์น ํ๋๋ ์ํ๋๋ ํ๋จํ๋ฉด ๋ฉ๋๋ค. ํน์  ๋ณ์๊ฐ ๋ฐ๋๋๋ฐ ์ด๋ฅผ ์บ์นํ๋ค๋ผ๋ฉด ๋ณ๊ฒฝ๋ ์ต์ ์ ๋ณ์์ ํจ๊ป useCallback, useMemo๋ฑ์ด ๊ฐฑ์ ๋ฉ๋๋ค. ๊ทธ๋ ์ง ์๋ค๋ผ๋ฉด ์์ ์ ๋ก์ ๋ณ์, ์ธ์คํด์ค๋ฅผ ๋ณด๊ณ ์๊ฒ ์ฃ ? - 0
- 2
- 56
 
- Q&A - getUser ์ ๊ฐ์๊ธฐ serverComponent๊ฐ ์ถ๊ฐ๋ ์ด์ ? - ์ฌ์ฉ์ฒ๊ฐ ๋ถ๋ช ํ ํจ์๋ผ๋ฉด ๊ฐ๋ฅํฉ๋๋ค.! ๊ฐ์ธ์ ์ผ๋ก๋ ์๋ฒ์ก์ ์ serverComponent ๋ฐ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ 2๊ณณ์ ๋ชจ๋ ์ฌ์ฉ๊ฐ๋ฅํ๋๋ก ๋ง๋๋๊ฒ ์ข์์ ์ด์ ๋ํ ๋ถ๊ธฐ ์ฒ๋ฆฌ ์ธ์๋ฅผ ๋จ๊ฒจ๋์์ฃ . ์๋ฐํ ๋งํ๋ฉด SSR ๊ณผ์ ์์ ํด๋น ํจ์ ํธ์ถ์ ์ผ๋ฐ ํจ์ ํธ์ถ ์ ๋๋ค. -> ์ฟ ํค ์กฐ์ ๋ถ๊ฐ๋ฅ. CSR ๊ณผ์ ์์ ํด๋น ํจ์ ํธ์ถ์ ์๋ฒ์ก์  ํธ์ถ ์ ๋๋ค. -> ์ฟ ํค ์กฐ์ ๊ฐ๋ฅ. - 0
- 2
- 59
 
- Q&A - getUser ์ ๊ฐ์๊ธฐ serverComponent๊ฐ ์ถ๊ฐ๋ ์ด์ ? - ์ฌ์ฉ์ฒ๊ฐ ๋ถ๋ช ํ ํจ์๋ผ๋ฉด ๊ฐ๋ฅํฉ๋๋ค.! ๊ฐ์ธ์ ์ผ๋ก๋ ์๋ฒ์ก์ ์ serverComponent ๋ฐ ํด๋ผ์ด์ธํธ ์ปดํฌ๋ํธ 2๊ณณ์ ๋ชจ๋ ์ฌ์ฉ๊ฐ๋ฅํ๋๋ก ๋ง๋๋๊ฒ ์ข์์ ์ด์ ๋ํ ๋ถ๊ธฐ ์ฒ๋ฆฌ ์ธ์๋ฅผ ๋จ๊ฒจ๋์์ฃ . ์๋ฐํ ๋งํ๋ฉด SSR ๊ณผ์ ์์ ํด๋น ํจ์ ํธ์ถ์ ์ผ๋ฐ ํจ์ ํธ์ถ ์ ๋๋ค. -> ์ฟ ํค ์กฐ์ ๋ถ๊ฐ๋ฅ. CSR ๊ณผ์ ์์ ํด๋น ํจ์ ํธ์ถ์ ์๋ฒ์ก์  ํธ์ถ ์ ๋๋ค. -> ์ฟ ํค ์กฐ์ ๊ฐ๋ฅ. - 0
- 2
- 62
 






