소개
마플, 뱅크샐러드 거쳐 현재는 당근에서 프론트엔드 엔지니어로 일하고 있습니다.
"난 네가 필요해", "너의 존재가 나에게 힘이 돼"라는 말을 좋아합니다. 이웃의 필요를 채워주고 힘이 되어 주는 것, 그게 사랑이라고 믿습니다. 좋은 강의로 여러분의 필요를 채우고 힘이 되어드릴 수 있도록 노력하겠습니다.
강의
수강평
- 손에 익는 Next.js - 블로그 만들기
- 손에 익는 Next.js - 블로그 만들기
- 손에 익는 Next.js - 공식 문서 훑어보기
게시글
질문&답변
배포 후, 조회수 증가 이슈
오, 이슬님! 안녕하세요! Vercel Postgres를 대체하는 Neon Marketplace 통합되었는지 몰랐네요... 변화가 정말 빠른 거 같습니다 😅 알려주신 것으로 시도해봤는데... 저도 동일한 증상이 발생하더라고요. 뭔가 이상해서 원래 예제로도 테스트를 해봤어요. 그랬더니 역시 동일하게 카운트가 2회 이상 오르는 문제가 생기는 걸 발견할 수 있었어요. (제 예제에 있던 버그를 발견해주셨어요. 감사해요!) 다시 알아보니 서버 컴포넌트의 중복 호출 문제로 보여요. 예제에서처럼 새로고침 마다 변경되어야 하는 경우라면 incrementView에 해당하는 로직을 Route Handlers로 구현하는 방식이 가장 쉬운 접근일 것 같아요.예제를 별도의 브랜치에 만들어뒀으니 확인 해주세요.https://github.com/hajoeun/next-js-blog/blob/fix/view-count/app/api/view-count/route.ts 더 알아보고 좋은 방법이 있다면 강의 소식에 남겨둘게요!문제를 발견해주셔서 너무 감사드립니다! 시도해보시고 결과 알려주세요. 문제가 있다면 또 질문 남겨주세요! 감사합니다.
- 1
- 1
- 74
질문&답변
추가로 Head tag에서 작성된 script 코드 관련하여 질문드리고 싶습니다. (feat. 즉시 실행 함수, dangerouslySetInnerHTML)
안녕하세요. 우성님! 1, 2번 질문에 이어서 답변 드릴게요. 4번 - 3번 순서로 답변드리겠습니다. A4. dangerouslySetInnerHTML를 사용하는 이유dangerouslySetInnerHTML를 쓰지 않고 script 태그에 themeEffect의 로직을 넣어보면 답을 알 수 있습니다. 서버에서 렌더링하는 시점의 HTML과의 차이가 발생해 Error: Text content does not match server-rendered HTML. 에러를 만나게 됩니다. Next.js 서버에서는 태그 안의 컨텐츠를 특수 문자를 엔티티로 이스케이프 처리합니다. 예를 들면 따옴표(')를 ' 이렇게 바꾸는거죠. 그 결과 브라우저에서 해석하는 결과와 차이가 생기는 것이죠. 반면 dangerouslySetInnerHTML을 사용하면 내용을 그대로 사용해 서버와 브라우저가 동일한 결과를 반환합니다.때문에 dangerouslySetInnerHTML을 사용했습니다. A3. 즉시 실행 함수를 사용한 이유dangerouslySetInnerHTML를 사용할 수 밖에 없는 상황이라는 점을 감안했을 때 결국 __html에서 테마 설정을 바꿔야 합니다. 이때 선택지는 두개가 있습니다. themeEffect 와 같은 함수를 즉시 실행문자열로 모든 themeEffect 함수 내의 로직을 적기저는 남겨주신 스코프 제한의 이유 외에도 에디터에서 지원하는 하이라이트 기능의 사용 편의나 코드의 가독성 측면에서 즉시 실행 함수가 유리하다고 판단했습니다. 즉시 실행 함수를 쓰는 일이 잦은 편은 아닙니다. 예전에는 useEffect 내에서 비동기 함수를 호출할 때 async/await 문법을 쓰기 위해 async로 선언한 즉시 실행 함수를 쓰곤 했는데 TanStackQuery와 같은 좋은 도구가 나오면서 이런 방법을 잘 쓰진 않습니다. 테마 변경 기능에 쓰인게 특이한 사례라고 보셔도 괜찮을 거 같아요! 답변이 되셨으면 좋겠네요. 또 다른 질문 있다면 얼마든 편하게 남겨주세요! 열심히 하시는 모습 보기 좋습니다! 응원할게요!
- 1
- 2
- 122
질문&답변
Head tag에서 script를 작성하는 이유에 대해서 여쭤보고 싶습니다! (+ NextJS의 Head tag와 Script tag)
우성님, 안녕하세요! 너무 좋은 질문들 남겨주셨네요. 하나씩 답변드려 볼게요. A1. 다크모드 설정을 localStorage에서 가져오는 부분에서 head에서 script를 사용하는 이유fouc 현상을 방지하기 위함이라고 보시는 게 맞습니다! A2. NextJS에서 제공하는 Head tag와 Script tag를 사용하지 않고 순수 HTML로 작성하신 이유Head 태그의 경우 Pages router에서 제공하는 컴포넌트로 알고 있어요. App router를 사용하는 저희 예제에서 사용하기에 적절하지 않은 컴포넌트 였습니다. Head 컴포넌트는 보통 메타데이터 설정을 위해 많이 사용합니다. 저희가 블로그를 Page router로 만들었더라도 Head 컴포넌트를 사용하지 않는 선택을 했을 것 같아요.Script 태그는 App Router에서도 제공하는 컴포넌트입니다. 하지만 Script 컴포넌트는 마치 Image 컴포넌트와 같은 역할을 하는 용도로 쓰입니다. 스크립트를 로드할 때 최적화를 하기 위해 쓰이죠. 저희가 구현한 HTML 순수 기능인 script 태그는 내부에서 자바스크립트 코드를 실행시키기 위해 쓴 경우라 상황이 조금 다르다고 볼 수 있을 것 같습니다. 좋은 질문 남겨주신 걸 보니 열심히 공부하고 계신 것 같아 너무 뿌듯합니다! 다른 질문이 있다면 또 편히 남겨주세요. 3, 4번 질문도 바로 답변 드릴게요! 감사합니다.
- 1
- 1
- 63
질문&답변
완강하고 질문 드립니다
안녕하세요! 강의 봐주셔서 진심으로 감사드립니다. 렌더링 기법의 경우 실무에서 필요에 따라 선택해서 사용합니다.SSR, CSR을 보통 혼용해서 사용합니다. 첫 렌더링에 SSR을 활용하고 이후 페이지 전환에 CSR을 적용하는 패턴이 흔히 보입니다.SSG, ISR의 경우 블로그나 회사 홈페이지 같은 정적인 컨텐츠를 제공할 때 많이 사용합니다.PPR의 경우 아직은 실무에서 널리 사용되는 기법은 아닙니다.개인적인 관찰에 따르면 CRUD까지 직접 구현한 블로그는 적은 편이라고 보입니다.티스토리나, 벨로그, 네이버 블로그 등의 블로그 서비스를 이용하는 경우가 아니라 직접 구현을 선택하는 경우에는 제 강의와 같은 마크다운 파일을 활용해서 구현하는 사례가 일반적입니다.요즘엔 옵시디언, 노션과 같은 메모 도구가 글을 퍼블리시할 수 있는 기능을 제공합니다. 이를 활용해서 블로그를 운영하는 사례도 종종 있습니다. (일부 유료로 알고 있어요)md 파일을 직접 작성하지 않고 글을 브라우저에서 작성/수정하려면 추가적인 기능을 붙여야 합니다. CMS(Content Management System)를 연계해서 개발하는 방법입니다. 아무래도 에디터를 직접 분이거나 외부 서비스를 연동하는 작업이다보니 직접 마크다운을 작성하는 것에 비해 개발에 힘을 더 쏟아야 한다는 단점이 있습니다. 빠르게 답변 드리고 싶어서 조금 건조하게 답변드렸는데, 더 자세한 이야기가 나누고 싶으시다면 추가로 질문 남겨주세요! 도움될 때까지 답변 드리겠습니다. 감사합니다. 하조은 드림
- 1
- 2
- 51
질문&답변
안녕하세요 generateStaticParams 관해서 질문
안녕하세요! 회신이 늦었습니다. 고민 많이 하고 계실텐데 답변이 늦어서 죄송합니다. 가능하다면 전체 코드를 알려주시면 확인이 조금 더 쉬울 것 같습니다. 짐작해보건데 빌드 시점에 prefetchQuery가 동작하면서 로그를 남기고 있는 게 아닐까 싶어요. 말씀주신 것처럼 Next.js의 캐시 있어서 중복 요청을 제거합니다. 이는 fetch 함수를 이용한 API 호출인 경우입니다. fetch 이전에 fetchBanner 내부에서 콘솔을 남기고 있는 것이라면 prefetchQuery 는 매번 호출될 수 있을 것 같습니다. 기다려주셨는데 명쾌한 답변을 드리지 못한 점 양해 부탁드립니다! 코드 저장소를 알려주시면 살펴보고 빠르게 답변 드릴게요!
- 0
- 2
- 147
질문&답변
다크모드 적용
안녕하세요! 라이브러리를 사용하지 않은 이유에 대해 질문 주셨네요 🙂 크게 두가지 이유가 있었습니다. 가급적이면 TailwindCSS 외의 추가 라이브러리를 사용하지 않고 구현하고 싶었습니다. 암묵지를 최대한 줄이고 싶었어요. 제가 해당 라이브러리의 존재를 몰랐습니다. 알았다고 하더라도 1번의 이유로 지금처럼 구현했을 거 같아요. 답변이 되셨으면 좋겠네요!다른 질문 있으시면 언제든 편하게 남겨주세요!
- 1
- 2
- 139
질문&답변
PPR 적용 한 후 에러가 났습니다.
안녕하세요!PPR 적용까지 오셨군요! 고생 많으셨습니다. 설치된 Next.js 버전을 봤을 때 Canary 버전이 아닌 것 같아요. PPR은 현재 Preview 기능으로 Canary 버전을 설치하셔야 활용해보실 수 있어요. Next.js 공식 문서를 참고하셔서 Canary 버전으로 Next.js를 설치해보시고 다시 시도해봐주세요! https://nextjs.org/docs/messages/ppr-preview 이후에도 문제가 있다면 언제든 질문 남겨주세요. 감사합니다.
- 1
- 2
- 135
질문&답변
CRA에서 Next.js로 마이그레이션하기에서 compilerOptions.moduleResolution bundler 불가
안녕하세요! 질문 남겨주셔서 감사합니다. 정확하게 말씀해주셨습니다. 말씀주신 것처럼 tsconfig.json의 compilerOptions.moduleResolution에 "bundler" 값은 TypeScript 5 이상에서 지원합니다. 때문에 해당 강의 중에 TypeScript 버전을 올리고 있습니다. 섹션 5. Next.js 설치하고 설정 파일 만들기 영상의 15초 지점을 참고해주세요. 질문 남겨주셔서 다시 감사드리며, 영상 확인 후에도 문제가 있다면 질문 남겨주세요!다른 질문도 언제나 환영입니다 🙂
- 0
- 1
- 90
질문&답변
next/image에 대한 질문
안녕하세요. 이미지 컴포넌트에 대해 질문 남겨주셨네요! AWS로 배포했을 때 next/image 때문에 비용이 더 올라가나요?next/image가 서버를 활용해 이미지 최적화를 하기 때문에 어느정도의 서버 운용 비용을 증가 시킬 수 있다는 의미로 질문을 해석했습니다. 이미지의 갯수, 페이지 방문 트래픽에 따라 차이가 있을 수 있지만 일반적인 경우라면 next/image를 사용한다고 해서 크게 차이날 정도는 아닐 것으로 예상합니다. next/image가 비용이 비싸다면 어떤 경우에 사용하는지 궁금합니다.이미지는 웹 서비스의 성능에 가장 많은 영향을 끼치는 요소입니다. 특히, LCP라고 부르는 지표에 큰 영향을 줍니다. 때문에 이미지 로딩 성능을 개선하면 웹 서비스의 성능 향상에 지대한 영향을 끼칠 수 있습니다. 이를 위해 Next.js에서는 next/image를 제공합니다. next/image는 다음과 같은 장점을 가지고 있습니다.디바이스 환경에 맞는 이미지 사이즈, 포맷으로의 자동 매칭레이아웃 시프팅 이슈 해결 (레이아웃 시프팅:이미지 로드 전과 후의 크기 차이에서 발생하는 레이아웃 트러짐 현상)이미지 지연 로딩으로 초기 로딩 속도 개선장점에 대한 자세한 내용은 공식 문서를 확인해보시면 좋을 것 같습니다. 결국 next/image를 사용했을 때의 장점이 어느정도의 비용 발생보다 큰 가치를 제공한다고 판단했을 때 next/image를 쓰는 것이라 말할 수 있을 것 같습니다. 질문 남겨주셔서 감사합니다.
- 1
- 1
- 121
질문&답변
데이터 재검증 방법
안녕하세요! 질문 남겨주셔서 감사합니다. 하나씩 답변드려볼게요! 클라이언트 컴포넌트에서 어떠한 동작을 수행한 후 데이터를 재검증 하려면 route handler로 요청을 보내고 route handler 내에서 revalidateTag 등을 사용하는 방법밖엔 없는걸까요?revalidateTag를 사용하는 이유에 대해 생각해보면 좋을 것 같습니다. 해당 함수는 캐시된 데이터를 비우고 새로운 데이터를 사용할 수 있도록 만들기 위해 사용합니다. 강의에서 캐시된 데이터는 서버에 존재하는 상태입니다. 때문에 서버에 있는 캐시를 비우기 위해 Route Handler를 이용해 서버에서 revalidateTag를 호출해 캐시를 비워야만 합니다. Route Handler를 이용하지 않고 서버에서 캐시를 비우는 방법으로는 Server Actions를 활용하는 방법이 있을 수 있습니다. 이는 강의에서 다루지 않았지만 공식 문서에서 다루고 있는 방식을 참고하시면 좋을 것 같습니다. 결국 서버에서 캐시된 값은 서버에서 해제해야 한다는 것이 규칙임을 알 수 있습니다. 직접 새로고침하지 않고 캐시를 지움과 동시에 바로 화면상의 모습도 갱신하려면 어떻게 해야 하나요?새로고침 없이 화면 상의 모습을 갱신하기 위해선 클라이언트 컴포넌트를 사용해야 합니다.새로고침 없이 데이터 갱신이 필요한 곳을 모두 클라이언트 컴포넌트로 활용하는 방법입니다. 이는 기본적인 React 활용 방식과 동일하게 API 응답값을 useState와 같은 상태로 저장해서 관리하는 방식입니다. next.js에서도 react처럼 axios를 많이 사용하나요?이번 App Router가 등장한 Next.js 13 이후에는 fetch 사용을 권장하고 있습니다. 캐시와 같은 성능 향상의 이점을 보기 위함입니다. 하지만 사용성 등에서 불편함을 느끼고 Axios와 같은 라이브러리를 쓰는 사례도 많습니다. 관련 사례를 소개하는 글을 남겨둘게요! https://blog.deercorp.com/next-js-app-router-and-fetch-library/추가 질문 있으시면 언제든 남겨주세요! 답변이 도움되셨으면 좋겠습니다.감사합니다.
- 1
- 2
- 138