묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
안녕하세요,
4월에 구매하여 늦게서야 해당 강의를 수강 중인데 업데이트 된 강의 쿠폰 발급하는걸 몰랐네요ㅠㅠ 혹시 현강의랑 많이 다를까요? 어떤 차이점이 있는지 궁금해요.듣는다고 하면 중간부터 들어야하나요. 현재 eslint부분 듣고있는데 애매하네요. 그리고 듣는다는 가정 하에 쿠폰 재발급이 가능한지 궁금합니다.
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
2.16) 빌드 후 실행한 환경에서 네트워크 탭에서의 Json 요청
안녕하세요. 좋은 강의 잘 듣고 있습니다. "2.16) SSG 4. 폴백옵션 설정하기" 강의를 듣다가 궁금한 점이 생겨서 질문남깁니다!홈 경로는 getStaticProps 함수를 사용해 빌드 타임에 사전 렌더링이 이루어지고 있습니다. Next App을 빌드 후에 홈 / 경로에서 네트워크 탭을 살펴보다가 현재 화면 내에서 인덱스에 해당하는 Json 응답을 받은 것을 보았습니다.하나를 열어보니 아래와 같습니다.// 6.json?id=6 { "pageProps": { "book": { "id": 6, "title": "프론트엔드 성능 최적화 가이드", "subTitle": "웹 개발 스킬을 한 단계 높여 주는", "description": "...", "author": "유동균", "publisher": "인사이트", "coverImgUrl": "https://shopping-phinf.pstatic.net/main_3562758/35627588630.20230704084326.jpg" } }, "__N_SSG": true }제가 이해한 바로는 / 경로에 진입해서 초기 요청이 이루어지면 서버는 사전에 렌더링 된 HTML 페이지를 응답한 이후 현재 페이지에 필요한 모든 자바스크립트 파일을 JS Bundle로 전달합니다.네트워크 탭에서 localhost HTML 문서를 확인하고 이후에 http://localhost:3000/_next/static/chunks/pages/book/%5Bid%5D-4bfc2418ccf58b5f.js JS Bundle을 응답받은 것을 확인했습니다.그리고 현재 페이지에서 이동 가능성이 있는 페이지들에 한해 사전에 요청이 이루어집니다. js 파일이 전달되어야 하지만 북(/book/[id])페이지가 SSG 방식으로 사전 렌더링이 이루어지므로 데이터를 뿌려주기만 하면 되니까 json 형식으로 응답이 온 것이 아닐까 생각했습니다. (북페이지를 SSR 방식으로 바꾸니 북페이지의 js 파일이 전달되었습니다.)이후 Link 컴포넌트인 도서 목록 중 하나를 클릭하면 자바스크립트 코드를 실행시켜 컴포넌트를 교체하는 CSR 방식으로 페이지를 이동합니다.Q. SSG 방식에서는 사전 렌더링의 응답으로 Json 형식으로 전달받아 새로운 페이지를 보여주는 제가 이해하고 있는 방식이 맞는지 궁금합니다.다른 하나는, 현재 화면에서 네트워크 요청(예: 6.json?id=6)이 무수히 많이 이루어진 것을 보았습니다. 그래서 Link 컴포넌트의 prefetch 값을 false로 설정하여 각 컴포넌트에 마우스를 호버했을 때 프리페칭이 이루어지도록 했습니다. 그러자 마우스를 호버하면 프리페칭이 이루어졌지만 마우스를 호버할 때마다 요청이 이루어져 의문이 생겼습니다.Q. 잦은 요청이 서버에 부하를 주는 것은 아닌지, 이를 개선할 수 있는 방법이 있는지 궁금합니다. 긴 글 읽어주셔서 감사합니다.아래 코드 첨부하였습니다!📄/pages/index.tsximport SearchableLayout from "@/components/Searchable-layout"; import BookItem from "@/components/Book-item"; import { InferGetStaticPropsType } from "next"; import fetchBooks from "@/lib/fetch-books"; import style from "./index.module.css"; import fetchRandomBooks from "@/lib/fetch-random-books"; export const getStaticProps = async () => { const [allBooks, recoBooks] = await Promise.all([ fetchBooks(), fetchRandomBooks(), ]); return { props: { allBooks, recoBooks, }, }; }; export default function Home({ allBooks, recoBooks, }: InferGetStaticPropsType<typeof getStaticProps>) { return ( <div className={style.container}> <section> <h3>지금 추천하는 도서</h3> {recoBooks.map((book) => ( <BookItem key={book.id} {...book} /> ))} </section> <section> <h3>등록된 모든 도서</h3> {allBooks.map((book) => ( <BookItem key={book.id} {...book} /> ))} </section> </div> ); } Home.getLayout = (page: NextPageWithLayout) => { return <SearchableLayout>{page}</SearchableLayout>; }; 📄/pages/book/[id].tsx/* eslint-disable jsx-a11y/alt-text */ /* eslint-disable @next/next/no-img-element */ import fetchBook from "@/lib/fetch-one-book"; import style from "./[id].module.css"; import { GetStaticPropsContext, InferGetStaticPropsType } from "next"; export const getStaticPaths = () => { return { paths: [ { params: { id: "1" } }, { params: { id: "2" } }, { params: { id: "3" } }, ], fallback: "blocking", }; }; export const getStaticProps = async (context: GetStaticPropsContext) => { const { id } = context.params!; const book = await fetchBook(Number(id)); return { props: { book, }, }; }; export default function Page({ book, }: InferGetStaticPropsType<typeof getStaticProps>) { if (!book) return "문제가 발생했습니다. 다시 시도해주세요."; const { title, subTitle, description, author, publisher, coverImgUrl } = book; return ( <div className={style.container}> <div className={style.cover_img_container} style={{ backgroundImage: `url('${coverImgUrl}')` }} > <img src={coverImgUrl} /> </div> <div className={style.title}>{title}</div> <div className={style.subTitle}>{subTitle}</div> <div className={style.author}> {author} | {publisher} </div> <div className={style.description}>{description}</div> </div> ); }
-
미해결Next + React Query로 SNS 서비스 만들기
middleware 관련 질문입니다
해당 코드를 수정했던 강의가 어디였는지 기억이 안나 여기에 글 남깁니다.아래는 auth.ts의 코드이고 callbacks 부분을 작성하셨다가 나중에 없애는 걸로 수정하셨는데 이 코드의 역할을 middleware에서 대신한다고 생각하면 될까요 ? export async function middleware() { const session = await auth(); if (!session) { return NextResponse.redirect('http://localhost:3000/i/flow/login'); } } // callbacks: { // async authorized({ request, auth }) { // if (!auth) { // return NextResponse.redirect('http://localhost:3000/i/flow/login'); // } // return true; // }, // },
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
마지막 강의 배포 후 최적화에서 오류
안녕하세요 next 강의를 거의 마치고 vercel에 배포까지 완료한 후 마지막 강의인 배포 후 최적화를 강사님과 동일하게 작성 후 vercel --prod 명령어를 통해 프로젝트를 다시 배포하였는데 해당 오류가 나타납니다.. ㅠㅠ book 폴더에서 오류가 나는것 같은데 혼자 해결해보려고 했으나, 원인도 잘 모르겠고 검색해도 잘 안나와서 여쭤봅니다.. -오류- -/book/[id]/page.tsx 코드-import { notFound } from "next/navigation"; import style from "./page.module.css"; import { BookData, ReviewData } from '@/types'; import ReviewItem from "@/components/review-item"; import ReviewEditor from "@/components/review-editor"; import Image from "next/image"; export async function generateStaticParams() { const response = await fetch(`${process.env.NEXT_PUBLIC_API_SERVER_URL}/book`); if(!response.ok) { throw new Error(response.statusText); } const books:BookData[] = await response.json(); return books.map((book) => ({ id: book.id.toString(), })) } async function BookDetail({bookId} :{bookId:string}) { const response = await fetch(`${process.env.NEXT_PUBLIC_API_SERVER_URL}/book/${bookId}`); if(!response.ok) { if(response.status === 404) { notFound(); } return <div>오류가 발생했습니다...</div> } const book = await response.json(); const { id, title, subTitle, description, author, publisher, coverImgUrl } = book; return ( <section> <div className={style.cover_img_container} style={{ backgroundImage: `url('${coverImgUrl}')` }} > <Image src={coverImgUrl} width={240} height={300} alt={`도서 ${title}의 표지 이미지`} /> </div> <div className={style.title}>{title}</div> <div className={style.subTitle}>{subTitle}</div> <div className={style.author}> {author} | {publisher} </div> <div className={style.description}>{description}</div> </section> ); } async function ReviewList({bookId}:{bookId : string}) { const response = await fetch(`${process.env.NEXT_PUBLIC_API_SERVER_URL}/review/book/${bookId}`, {next:{tags:[`review-${bookId}`]}}); if(!response.ok) { throw new Error(`Review fetch failed : ${response.statusText}`); } const reviews:ReviewData[] = await response.json(); return ( <section> {reviews.map((review) => ( <ReviewItem key={`review-item-${review.id}`} {...review} /> ))} </section> ) } export async function generateMetadata({ params }: { params: Promise<{ id: string }> }) { const {id} = await params; const response = await fetch(`${process.env.NEXT_PUBLIC_API_SERVER_URL}/book/${id}`); if(!response.ok) { throw new Error(response.statusText); } const book:BookData = await response.json(); return { title:`${book.title} - 한입북스`, description:`${book.title}`, openGraph:{ title:`${book.title} - 한입북스`, description:`${book.title}`, images:[book.coverImgUrl], } } } export default async function Page({ params }: { params: Promise<{ id: string }> }) { const resolvedParams = await params; return ( <div className={style.container}> <BookDetail bookId={resolvedParams.id} /> <ReviewEditor bookId={resolvedParams.id} /> <ReviewList bookId={resolvedParams.id} /> </div> ) }
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
[06-01] 동기/비동기는 강의 영상이 없나요?
강의 시간이 1분이고 영상 자체가 없어서요.그냥 학습자료만 보고 넘어가는 부분인가요?그리고 전체 강의 코드는 어디서 다운로드 받을 수 있나요?
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
오류2
Next 강의에서 App Router 실습을 위해서 강사님께서 올려주신 자료를 다운받으면위 사진과 같이 강의와는 다르게 Promise 타입이 존재하여 params.id에 오류가 발생하게 됩니다.
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
오류
Next 강의에서 App Router 실습을 위해서 강사님께서 올려주신 자료를 다운받으면위 사진과 같이 강의와는 다르게 Promise 타입이 존재하여 searchParams.q에 오류가 발생하게 됩니다.그래서 Promise 타입을 없애면 오류는 사라지지만 빌드타입에 오류가 아래와 같이 발생합니다. 어떻게 해결하면 될까요?
-
해결됨[코드캠프] 부트캠프에서 만든 고농축 프론트엔드 코스
eslint와 prettier
eslint를 설치하면 이전과 달리 esling.config.mjs로 파일이 설정되며 extend나 rules의 활용이 기존과 다른 방식으로 진행되며 충돌이 일어납니다. stackoverflow나 chatGPT의 도움을 받아 동작은 되지만, 이 부분 다시 설명해주셔야 하는게 아닌지요. (기존에 설명된 부분들도 코드나 적용방식이 달라져서, 플러그인을 활용하도록 합니다)이 부분을 스스로 혼자 찾아서 수정할 수 있는 역량이 있다면 이 강의를 듣지 않겠지요. 하루 종일 한단원도 나가지 못하고 .. 해결하려다 포기하게 되네요. 2년전에 산 강의를 시간이 없어 이제 듣는 제 문제도 있겠지만.. 이 부분 상세한 설명을 넣어주셔야 할것 같아요.
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
혹시 백엔드서버를 종료해도 에러가 뜨지안고 정상가동되면 어떻게해야하나요?
혹시 백엔드서버를 종료해도 에러가 뜨지안고 정상가동되면 어떻게해야하나요?.. 당황스럽네요 하하 아 캐싱문제네요 강제 새로고침으로 해결했습니다.감사합니다. 음 아니네요 여전히 이상하네요..전 이상하게 Footer에서 먼저 에러가 나네요.force cache가 되어있음에도.. 왜그럴까요?ㅜㅜ
-
미해결한 입 크기로 잘라먹는 Next.js(v15)
배포 환경에서 fetch 오류
실제 https로 배포된 API를 fetch를 활용하여 SSR을 구현하고있습니다.문제는 local에서는 yarn build -> yarn start 하고 테스트를 진행하면 fetch가 정상적으로 작동합니다.하지만 AWS Amplify를 활용하여 Next JS를 배포하고 배포한 사이트에서 fetch(pending 이후에 catch로 빠짐)가 작동하지않습니다.API에 문제가 있나해서 다른 API를 CSR로 테스트를 해보면 정상적으로 200이 됩니다.원인이 뭘까요?
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
static 페이지vs 다이나믹 페이지
폴라우트 페이지 2를 보면서 / 인덱스페이지가 강사님은 static 페이지가 아닌 다이나믹 페이지로 빌드가 되는 부분에서 강사님은 fetch에 force-cache를 적용시키면서 이제 다이나믹된 페이지를 static 페이지로 바꾸셨느데 일단 저는 force-cache 옵션을 적용을 안해도 static 페이지이더라구요강사님과 저랑 다른 점은 api호출하는 함수 부분을 따로 api 폴더에 빼둔거 말고는 다른 점은 없습니다 .이렇게 따로 빼놓은 뒤 그냥 promis.all로 데이터 패칭을 해서 그대로 화면에 보여줬습니다 (이것저것 시험하느라 Allbook ,RandomBook 컴포넌트를 따로 빼지는 않은 상태입니다. )export default async function Home() { const [allBooks, randomBooks] = await Promise.all([ fetchBooks(), fetchRandomBook(), ]);저는 force-cache 를 적용안햇는데도 왜 다이나믹 페이지가 안되고 static 페이지가 되는걸까요 ...
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
제가 뭐 건들었는지 안되네요 이유를 알 수 있을까요?
// CssModulePage.jsx import styles from "./styles.module.css"; export default function CssModulePage() { return ( <> <button className={styles.버튼스타일}>버튼</button> <div className={styles.네모상자스타일}>네모상자</div> </> ); }.버튼스타일 { background-color: yellow; } .네모상자스타일 { width: 200px; height: 200px; }Server ErrorError: The default export is not a React Component in "/section04/04-03-css/page"
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
강의 타임 질문입니다
영상이 18분쯤 마무리 되는 것 같은데 영상길이가 87분으로 검은화면만 노출됩니다확인 부탁드려요!
-
미해결Next + React Query로 SNS 서비스 만들기
서버 액션에서 msw의 핸들러를 호출하는 이유?
제가 알기로는 서버 액션은 현재 url, 강의 기준 /i/flow/signup으로 네트워크 요청이 일어나는거로 알고 있는데 msw의 핸들러로 fetch를 하신 이유가 궁금합니다. 작동하는 코드인가요?const onSubmit = async (formData: FormData) => { "use server"; let shouldRedirect = false; try { const res = await fetch(`${process.env.NEXT_PUBLIC_BASE_URL}/api/users`, { method: "post", credentials: "include", body: formData, }); console.log(res.status); console.log(await res.json()); shouldRedirect = true; } catch (error) { console.error(error); } if (shouldRedirect) { redirect("/home"); } console.log("실행됨"); };위 코드는 SignupModal에서 msw의 핸들러로 form 제출 요청을 보내는 코드이고,http.post(`${baseUrl}/api/users`, () => { console.log("로그인 성공"); return HttpResponse.json({ message: "msw 성공", }); }),이 코드는 핸들러 코드입니다. 요청 url인 http://localhost:3000/api/users로 폼 제출이 정상적으로 이루어지는지 궁금합니다.
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
오류
아직 사용하기 전에 변수들이 있는 경우 아래 사진과 같이 표시되는데 오류가 발생하지 않도록 설정은 어떻게 하나요?
-
해결됨[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
03-02 회원가입 질문
왼쪽처럼 입력하는 박스를 박스모양이 아니라 밑줄만 나오게 하려면 어떻게 해야하나요?
-
미해결[코드캠프] 부트캠프에서 만든 '완벽한' 프론트엔드 코스
03-02 회원가입 피그마에 나온거 처럼 만드는문제
섹션 03-02 마지막 부분에 나오는 회원가입 피그마 화면처럼 만들기 문제에 대한 답은 업로드 되어있나요? 답을 확인할수 없을까요??
-
미해결손에 익는 Next.js - 블로그 만들기
PPR 적용 후 여전히 SSG로 배포되는 이슈
안녕하세요 조은님!! 😀 강의 너무 잘봤고 완강 후 질문 남깁니다!마지막 기능인 PPR와 Suspense를 적용한 이후에 html에서 확인해봤을 때 동적인 요소로 채워지고 있는 것을 확인할 수 있었습니다.그런데 Vercel에서 Build Logs를 확인해보면◐ (Partial Prerender) 으로 뜨는 것이 아니라 여전히 ● (SSG) prerendered as static HTML 으로 뜨는데요, PPR 적용이 잘 된게 맞을까요?Suspense가 적용이 잘 되는데 PPR은 적용이 안된걸까요? 코드 작업 후 적용결과 첨부하겠습니다!
-
해결됨한 입 크기로 잘라먹는 Next.js(v15)
ssr질문
🚨 아래의 가이드라인을 꼭 읽고 질문을 올려주시기 바랍니다 🚨질문 하시기 전에 꼭 확인해주세요- 질문 전 구글에 먼저 검색해보세요 (답변을 기다리는 시간을 아낄 수 있습니다)- 코드에 오타가 없는지 면밀히 체크해보세요 (Date와 Data를 많이 헷갈리십니다)- 이전에 올린 질문에 달린 답변들에 꼭 반응해주세요 (질문에 대한 답변만 받으시고 쌩 가시면 속상해요 😢)질문 하실때 꼭 확인하세요2.11 번 강의에서 ssr 듣다가 궁금한점이 있어서요 ssr은 두번 렌더링이 일어난다고 하셧느데 그러면 첫번째 서버에서 렌더링된 뒤에는 undefined이고 두번째 하이드레이션이 일어나고 그 뒤에는 window가 있으니 밑에처럼 했을때에는 콘솔이 나온느게 맞을까요 ?(하이드레이션 적용된 뒤에가 맞을까요 ?) if (typeof window !== "undefined") { console.log("window.location", window.location); }
-
미해결Next + React Query로 SNS 서비스 만들기
SessionProvider을 사용해도 하위 컴포넌트가 서버 컴포넌트로 유지되는 것 같은데 이유가 궁금합니다.
SessoinProvider을 사용할 경우 SessionProvider로 감싼 하위 컴포넌트는 모두 클라이언트 컴포넌트가 되는 걸로 알고 있고 클라이너트 컴포넌트의 자식으로써는 서버 컴포넌트가 올 수 없다고 본 것 같은데 코드를 보니까 SessionProvider의 하위 컴포넌트도 서버 컴포넌트로 잘 작동 되는 컴포넌트가 있는 것 같아요.혹시 제가 잘못알고 있는지 궁금합니다.