묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실습으로 마스터하는 OAuth 2.0: 기본부터 보안 위험까지
수강 기간 연장 문의
안녕하세요. nextjs 몰라서 안듣고 공부하고 들어야지 하다가.. 수강기간 오늘이 마지막이라 허겁지겁 들었습니다. 가능하다면 1~2달 정도만 수강기간을 연장할수 있을까요?? 부탁드립니다..
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
Vercel 배포 후 revalidate
안녕하세요! 2.20 강의를 듣고 Vercel에 배포까지 한 뒤에 궁금한 점이 생겨 질문 드립니다! 이전 강의 실습에서는 인덱스 페이지의 추천 도서를 On-Demand ISR 방식으로 적용한 뒤 직접 주소를 입력해 페이지 요청을 보내서 바꾸었는데 Vercel에 배포한 뒤에는 어떻게 요청을 보내서 추천 도서 목록을 바꿀 수 있나요? 아니면 시간 단위로 업데이트하는 방식으로 다시 바꾸어서 작성한 뒤 재배포하나요?
-
미해결Next.js 완벽 마스터 (v15): 노션 기반 개발자 블로그 만들기 (with 커서AI)
9분경 진행한, 태그 필터링 관련 서버사이드 변경에 대한 질문
안녕하세요!먼저 좋은 강의 감사합니다. 중간쯤, 전체 데이터를 조회해서 Client 측에서 필터링 해서 사용하는게 아닌, 서버로부터 이미 필터링 된 데이터를 받아오도록 검색 api 를 수정한 내용입니다. 이 부분이 클라이언트 사이드 -> 서버 사이드로 변경하였다, 라는 내용을 설명주셨는데, 랜더링과는 전혀 관계 없는 데이터 필터링 주체를 말씀 하시 내용이라고 생각되는데 맞게 이해했는지 궁금합니다.즉, Notion = 서버, Next.js=클라이언트 관점으로 애기 하신게 맞는지 궁금합니다.
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
[18-05 게시글 이미지와 함께 등록] 타입 지정 질문드립니다
안녕하세요!! 강의 너무나도 잘 듣고 있습니다. 18-05 게시글 이미지와 함께 등록 23:25분에서 file에 대한 타입을 지정을 할 때 알려주신 방법 외에도 ! 를 이용해서 해결을 의도치 않게 했는데,구글 및 스택오버플로우에도 Argument of type ' file | undefined' is not assignable to parameter of type 'File'. Type 'undefined' is not assignable to type 'File'.ts(2345)해당 오류를 검색해보았지만 알려주신 방법들 외에는 느낌표를 사용하는 방법은 찾지 못했습니다.이게 왜 되는건지... 도통 알수가 없네요... 이건 어떤 원리인가요??항상 감사드립니다.
-
미해결Next.js 까보기: "쓸 줄 아는 개발자"에서 "알고 쓰는 개발자"로
'왜 Next.js 가 필요할까?(기술적인 등장 배경)' 에서 언급하는 영상들이 무엇일까요?
1강 '왜 Next.js 가 필요할까?(기술적인 등장 배경)' 에서 언급하신 영상들이 무엇인지 궁금해서 질문드립니다. 04:40"이 비동기에 대한 의미는 한 번 설명드린 적이 있어요." 10:00"서버 사이드 렌더링 시간에 저희가 이미 공부했으니까요." 두 지점에서 언급하신 Youtube 영상이 각각 무엇인지 URL을 알려주실 수 있으실까요?
-
해결됨[풀스택 완성] Supabase로 웹사이트 3개 클론하기 (Next.js 14)
smtp부분
✅ 모든 질문들은 슬랙 채널에서 답변드리고 있습니다.💡 ”로펀의 인프런 상담소” 슬랙 채널 가입하기 💡평일중에는 퇴근 이후(저녁 7시)에 답변을 받아보실 수 있고, 주말중에는 상시 답변드리고 있습니다. 안녕하세요, smtp 부분 이메일 인증 부분 진행하고있는데,smtp를 설정해야하는건가요? 그렇다면 어떻게 설정해야할까요?리센드를 이용하면 도메인이 무조건 필요한거같아서요
-
미해결Next + React Query로 SNS 서비스 만들기
@modal/(i) 로 생성/파일이동 후, 무한 GET 출력
강의의 3분 정도 쯤에,(beforeLogin)/i 폴더와 파일들을 (beforeLogin)/@modal/(i) 로 복사 한 후http://localhost:3000/i/flow/login 접속시 무한 GET 접속 시도가 터미널 창에 보입니다.이때, <Link href="login" className={styles.login}>로그인</Link> 입니다. 그런데, <Link href="/i/flow/login" className={styles.login}>로그인</Link> 변경하면, http://localhost:3000/i/flow/login 접속시, 터미널 창에서는 무한 GET 접속시도는 사라집니다.어떻게 해서 이렇게 되는지요?
-
미해결Next + React Query로 SNS 서비스 만들기
인터셉팅 라우트 설명
강의 50초 정도에, i, login, page.tsx는 {children}에서 렌더링, 여기는 (@modal 의 하위 폴더와 파일 선택) {modal}에서 되죠? 라고 설명하시는 부분이 이해가 안됩니다.저는, app/(beforeLogin)/layout.tsx 의 {children}은 app/(beforeLogin)/page.tsx 를 가져오는 것이고, {modal}은 @modal 폴더의 page.tsx (default.tsx, i/flow/login/폴더로 리다이렉션) 를 찾는 것으로 이했습니다.여러 폴더를 모두 보여준다고 설명하신듯하여, 이해가 안되네요.
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
npm_access_token 오류
npm_access_token 오류어떻게 해결하나요 ㅠㅠ
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
dynamic= "auto"으로 설정했을 경우 동적인 페이지로 설정
제목 그대로 export const dynamic = "auto";로 설정을 해도 해당 페이지가 정적인 페이지임에도 동적인 페이지로 빌드되는데 이게 맞을까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
쿠폰 발급 관련
기존강의 업데이트를 지금 확인해서 쿠폰 받을 수 있을까요
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
목데이터 불러오는 단계에서부터 막혔어요
2.9> 한입북스 UI 구현하기 13분강의하고 똑같이 따라해보고 안 되길래 깃헙에서 복붙에서 붙여 놔도 안되는데 이러면 다른 파일이 틀렸을 가능성이 있나요?
-
미해결Next + React Query로 SNS 서비스 만들기
재랜더링 최적화 문제
안녕하세요. 제가 직접 tailwind css v4를 이용해서 트위터 클론코딩을 진행하고 있는데SearchForm에서 입력이 이루어지면, SearchForm의 영향으로 인해서 다른 영역에서도 재랜더링이 일어나는 것 같습니다.먼저 묻고싶은 내용은 어떻게 하면 다른 영역은 재렌더링이 일어나지 않게 할까 입니다. 리엑트 개발자 도구로 렌더링이 일어날때 하이라이트 표시를 켰습니다. 이 때 SearchForm에 입력이 일어나면 위와같이 SearchForm만 아닌, 다른 영역에도 렌더링이 되는 모습이 보입니다. SearchForm 구성은 다음과 같이했습니다.최대한 현재 트위터의 입력 방식을 맞추어 보았습니다."use client"; import { useSearchParams } from "next/navigation"; import React, { useRef, useState, ChangeEventHandler, useEffect, memo, } from "react"; interface SearchFormProps { q?: string; } const SearchForm = () => { const [value, setValue] = useState(""); const inputRef = useRef<HTMLInputElement>(null); const searchParams = useSearchParams(); const search = searchParams.get("q"); const handleChange: ChangeEventHandler<HTMLInputElement> = (e) => setValue(e.target.value); const handleClear = () => { setValue(""); inputRef.current?.focus(); }; useEffect(() => { setValue(search ?? ""); }, []); return ( <div className="relative w-inherit h-12 group min-w-0"> {/* Border 레이어 */} <div className={` absolute inset-0 border border-default-border rounded-full transition-all duration-75 group-focus-within:border-2 group-focus-within:border-twiiter-blue `} /> {/* 내부 요소 컨테이너 */} <div className="relative w-full h-full"> <form className="flex items-center w-full h-full px-4" autoComplete="off" onSubmit={(e) => e.preventDefault()} > {/* 검색 아이콘 (외부 div 기준 위치) */} <svg className="absolute left-4 top-1/2 -translate-y-1/2 text-gray-500 pointer-events-none" width={20} height={20} viewBox="0 0 24 24" aria-hidden="true" fill="none" stroke="currentColor" strokeWidth={2} > <circle cx="11" cy="11" r="8" /> <line x1="21" y1="21" x2="16.65" y2="16.65" /> </svg> {/* Input */} <input ref={inputRef} type="search" placeholder="검색" value={value} onChange={handleChange} className=" w-full h-full pl-10 pr-10 bg-transparent text-base outline-none placeholder-gray-500 appearance-none " /> {/* Clear 버튼 (외부 div 기준 위치) */} {value && ( <button type="button" onClick={handleClear} className=" absolute right-3 top-1/2 -translate-y-1/2 w-7 h-7 flex items-center justify-center bg-gray-700 hover:bg-gray-800 rounded-full transition " tabIndex={-1} aria-label="Clear" > <svg width={16} height={16} viewBox="0 0 20 20" fill="white"> <path d="M10 8.586l4.95-4.95 1.414 1.414L11.414 10l4.95 4.95-1.414 1.414L10 11.414l-4.95 4.95-1.414-1.414L8.586 10l-4.95-4.95L5.05 3.636 10 8.586z" /> </svg> </button> )} </form> </div> </div> ); }; export default SearchForm; 이를 SearchHeader에 적용하였으며.import React from "react"; import SearchTab from "./SearchTab"; import SearchForm from "@/components/common/SearchForm"; const SearchHeader = () => { return ( <div className="w-[calc(100%-72px)] sm:pl-0 sm:max-w-[598px] fixed backdrop-blur-lg border-b-1 border-default-border bg-white/70 dark:bg-black/30"> <div className="w-full mt-2"> <SearchForm /> </div> <div className="w-full mt-1 h-[53px]"> <SearchTab /> </div> </div> ); }; export default SearchHeader; 최종적으로 /search 페이지에 이를 적용했습니다.import React from "react"; import Post from "../home/_components/Post"; import SearchHeader from "./_components/SearchHeader"; interface SearchPageProps { searchParams: Promise<{ q: string; f?: string; pf?: string }>; } const SearchPage = async ({ searchParams }: SearchPageProps) => { const { q } = await searchParams; return ( <main className="main-container"> <SearchHeader /> <div className="mt-[107px]"> <Post /> <Post /> <Post /> <Post /> <Post /> <Post /> <Post /> <Post /> <Post /> </div> </main> ); }; export default SearchPage; 관련된 layout.tsx는 다음과 같습니다.import Image from "next/image"; import Link from "next/link"; import React, { ReactNode } from "react"; import logo from "@/../public/twitter-logo.svg"; import SearchForm from "@/components/common/SearchForm"; import NavMenu from "./_components/NavMenu"; import LinkButton from "@/components/common/LinkButton"; import FollowCard from "./_components/FollowCard"; import TrendCard from "./_components/TrendCard"; import RightSection from "./_components/RightSection"; interface AfterLoginLayoutProps { children: ReactNode; modal: ReactNode; } const AfterLoginLayout = ({ children, modal }: AfterLoginLayoutProps) => { return ( <div className="overflow-y-scroll"> <div className="flex items-stretch"> <header className="flex items-end flex-col sm:flex-grow-1"> <section className="w-[72px] p-2 xl:p-0 xl:w-[275px] h-dvh"> <div className="flex flex-col w-inherit h-dvh fixed "> <Link href={"/home"}> <div className="w-14 h-14 rounded-[50%] flex justify-center items-center hover:bg-[rgba(15,20,25,0.1)]"> <Image src={logo} alt={"twitter logo"} width={40} height={40} /> </div> </Link> <NavMenu /> </div> </section> </header> <div className="flex items-start flex-col h-dvh flex-grow-1"> <div className="h-full w-[100%] sm:w-[600px] lg:w-[920px] xl:w-[990px] flex justify-between "> <main className="w-full sm:max-w-[600px] min-h-full h-fit border-l-1 border-r-1 border-default-border"> {children} </main> <div className="hidden lg:block lg:w-[290px] xl:w-[350px] h-fit relative"> <div className="flex flex-col w-inherit h-dvh fixed pt-1"> <RightSection /> </div> </div> </div> </div> </div> {modal} </div> ); }; export default AfterLoginLayout; SearchForm에 React.memo를 적용을 해보아도 변하지 않았습니다.(다른 영역, 예를 들어 main이 아닌 양 옆의 영역들에 대해서도 React.memo를 넣었지만 그래도 렌더링이 일어나고 있습니다.) 재랜더링 조건은 부모 컴포넌트가 재랜더링 되거나, props가 바뀌거나, state 변경이 일어났을 때인걸로 알고 있습니다.searchForm에서 Input만 영역에만 영향을 줘야할 것이 분명한데, 전체 영역에서 재랜더링이, 즉 layout.tsx에서 재랜더링이 일으키고 있는것 같습니다. (부모 영역) 혹시 렌더링이 어디까지 일어나는지 확인하는 (즉 최종 부모 컴포넌트까지) 방법이 있나요?그리고 이런 문제가 있을때 어떻게 최적화 할 수 있나요?p.s. 코드상 w-inherit 클래스가 이면 제가 직접 tailwind css utility에 추가하여 기능하도록 만들었습니다.+ 추가console.log()로 재랜더링이 일어나는지 확인해 보았는데 콘솔이 뜨지 않아 재랜더링이 아닌 다른 무슨 활성화(?) 인것 같아 보입니다... 하지만 SearchForm 입력 가지고 무언가 활성화 되는 것 자체가 조금 이해가 되지 않아서... 일단 재랜더링이라고 표현으로 남겨두었습니다...
-
미해결한 입 크기로 잘라먹는 Next.js(v15)
강사님의 로그와 저의 리퀘스트 메모이제이션 로그가 달라요!
넥스트 서버에서 찍히는 로그가 달라서 문의드립니다.다만 제가 백엔드쪽에서 콘솔을 찍어보니까 넥스트 로그와는 별개로 한번씩만 호출되는걸로 보여지는데 리퀘스트 메모이제이션이 잘 동작하는게 맞는지 궁금합니다 넥스트 로그 네스트 컨트롤러 로그
-
해결됨[풀스택 완성] Supabase로 웹사이트 3개 클론하기 (Next.js 14)
모듈 에러
✅ 모든 질문들은 슬랙 채널에서 답변드리고 있습니다.💡 ”로펀의 인프런 상담소” 슬랙 채널 가입하기 💡평일중에는 퇴근 이후(저녁 7시)에 답변을 받아보실 수 있고, 주말중에는 상시 답변드리고 있습니다. 모듈 에러가 뜨는데 수파베이스 설치를 잘못 한 것일까요? 검색해서 이리 저리 해보아도 잘 해결이 되지 않네요. 도와주세요~
-
해결됨Next.js 까보기: "쓸 줄 아는 개발자"에서 "알고 쓰는 개발자"로
Parallel Route를 사용한 모달에 대해 질문이 있어요.
하드 내비게이션(새로고침, 직접 URL 접근) 불가라고 하셨는데, default.js를 활용하면, 딥 링킹과 공유 가능 URL을 지원할 수 있는걸까요??
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
서버 컴포넌트 console.log
앱 라우터의 데이터 패칭 수업 중 서버 컴포넌트에서 찍은 콘솔창은브라우저에서는 보이지 않는다고 하시는데 브라우저 콘솔에 아주 잘보이거든여? 제가 잘 못 이해한걸 까요? // 랜덤으로 추천도서 가져옴 async function RecoBooks() { //api로 데이터를 불러오면 타입스크립트는 어떤 결과값을 가져올지 몰라 타입정보를 지정해줘야한다. const response = await fetch( `${process.env.NEXT_PUBLIC_API_SERVER_URL}/book/random` ); //예외처리 필수 if (!response.ok) { return <div>오류가 발생했습니다...</div>; } const recoBooks: BookData[] = await response.json(); //타입 : BookData[] console.log("랜덤 => ", recoBooks); //정상적으로 불러와서 렌더링까지 확인할 수 있다. return ( <div> {recoBooks.map((book) => ( <BookItem key={book.id} {...book} /> ))} </div> ); } export default function Home() { //async 제외 // 인덱스 페이지 return ( <div className={style.container}> {/* section 태그는 div 태그와 이름만 다른뿐 기능은 같다 */} <section> <h3>지금 추천하는 도서</h3> {/*books은 mock폴더안에 임시 배열데이터, list 형태로 렌더링 */} <RecoBooks /> </section> <section> <h3>등록된 모든 도서</h3> <AllBook /> </section> </div> ); }
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
서버 컴포넌트의 렌더링 과정
Next.js의 App Router 강의를 듣다가 헷갈리는 부분이 있어서 질문 드립니다!서버 컴포넌트로 초기 접속을 하게 되면 서버에서 RSC Payload와 HTML을 렌더링해서 브라우저에 보여주는걸까요? 아니면 RSC Payload가 직렬화한 HTML 정보를 가지고 있어서 바로 브라우저에 보내지는걸까요? 공식 문서에는 하이드레이션을 한다고 되어 있는데 하이드레이션을 하게 되면 두 번 렌더링이 되는거 아닌가요?? Link를 통해 서버 컴포넌트로 이동하게 되면 클라이어트 컴포넌트가 이동하는 것처럼 CSR 방식으로 동작을 하는건가요? 만약 동작을 한다 그러면, prefetch된 RSC Payload를 통해서 브라우저가 새로운 UI를 구성하는건가요?
-
해결됨바이브 코딩: Next.js + FastAPI + Faster-Whisper로 음성 메모 앱 만들기
ConnectionRefusedError: [WinError 1225] 원격 컴퓨터가 네트워크 연결을 거부했습니다
ConnectionRefusedError: [WinError 1225] 원격 컴퓨터가 네트워크 연결을 거부했습니다자꾸 이렇게 뜨면서 실행이 안되는데 어떻게 해야되나요?
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
npx prisma db push 오류 해결 부탁드립니다.
이미 다른 분들이 동일하거나 비슷한 경우를 많이 올려주셔서 다시 해봐도 도저히 해결이 안되어 문의 글 남깁니다..env 생성했고...# Connect to Supabase via connection pooling DATABASE_URL="postgresql://postgres.zbjatvpiqrregrejqyok:akswlwlak29@aws-0-ap-northeast-2.pooler.supabase.com:6543/postgres?pgbouncer=true" # Direct connection to the database. Used for migrations DIRECT_URL="postgresql://postgres.zbjatvpiqrregrejqyok:akswlwlak29@aws-0-ap-northeast-2.pooler.supabase.com:5432/postgres" 이렇게 오류가 발생합니다.C:\Users\BANG\Documents\onebite-books-server-main\onebite-books-server-main>npx prisma db pushEnvironment variables loaded from .envPrisma schema loaded from prisma\schema.prismaDatasource "db": PostgreSQL database "postgres", schema "public" at "aws-0-ap-northeast-2.pooler.supabase.com:5432"Error: Schema engine error:FATAL: Tenant or user not foundsupabase에서 계속 프로젝트 삭제 후 재생성해보고 비번도 바꿔봐도 동일한 증상입니다.확인 부탁드립니다.