전체 글

· ETC/Error
react-snowfall 라이브러리를 사용하던 도중 다음과 같은 오류가 발생했다. 해결 방법으로 useLayoutEffect가 클라이언트 사이드에서만 독점적으로 렌더링되어야 한다는 부분이 언급된 걸 보면, Next.js의 서버 사이드 렌더링 방식으로 인해 오류가 발생된 듯하다. Warning: useLayoutEffect does nothing on the server, because its effect cannot be encoded into the server renderer's output format. This will lead to a mismatch between the initial, non-hydrated UI and the intended UI. To avoid this, useLayo..
· Next.js
테스트를 마치고 나면 사용자의 별점과 등수가 표시되는데, 해당 정보를 트위터와 카카오톡에 공유하는 기능을 만들었다. 트위터 공유 트위터에 공유하기는 굉장히 간편했다. 아래와 같이 url에 공유를 원하는 url 주소를 입력하고, text에 추가로 필요한 텍스트를 입력하면 된다. window.open() 메서드를 버튼 형태로 만들면 해당 코드가 바로 열린다. https://twitter.com/share?url=url&text=text { window.open( `https://twitter.com/share?url=https://divdivdiv.com/cinephile&text=나의 시네필 평점은?${starCount}` ); }} > 트위터 공유하기 ; 카카오톡 공유 카카오톡 공유 기능을 쓰려면 카카오..
· Next.js
시네필 테스트에는 크게 4가지 타입의 페이지가 있다. 먼저 인덱스 페이지에서는 사용자의 닉네임을 입력받을 수 있고, 하단 버튼을 누르면 테스트 페이지로 이동한다. 테스트 페이지에는 테스트를 위한 문제들을 순서대로 보여준다. 마지막 문제인 25번째 문제에서 하단 버튼을 누르면 결과 페이지로 이동한다. 결과 페이지의 하단에는 참가자의 테스트 결과를 포함해 트위터/카카오톡 공유, 재도전, 해설지 버튼이 있다. 해설지 페이지에는 모든 문제의 정답과 해설을 제공한다. 모든 페이지는 비슷한 레이아웃을 공유하고 있으면서도 페이지 타입에 따라 서로 다른 콘텐츠와 기능을 가지고 있다. 이를 효율적으로 반영하기 위해 상태 변수를 활용하는 방식을 선택했다. pageType이라는 상태 변수는 하단 버튼(handleButton..
· Next.js
모듈화의 필요성 이 프로젝트는 영화에 관한 25개의 퀴즈를 풀 수 있는 사이트인데, 코드를 짜면서 문제를 여러 번 수정하거나 삭제하는 과정을 거쳤다. 그런데 중간중간 문제를 새로 추가하거나 순서를 바꾸는 일, 해당 부분을 찾아 블록 단위로 코드를 옮기거나 변경하는 일이 매우 불편하게 느껴졌다. 결과적으로 프로젝트를 완성한 다음, 모든 문제를 별도의 라이브러리에 모듈 형태로 저장하는 리팩토링 작업을 했다. 모듈 활용 각각의 문제를 객체 형태로 만들고 난 뒤, question, answer, options를 키로 설정했다. 또 문제의 type과 caption, reference라는 특수 항목을 만들어 문제가 주관식인 경우, 그리고 문제를 다 풀고 나서 제공되는 해설지에서도 이 모듈을 효과적으로 활용할 수 있..
· Gatsby
Gatsby와 SEO Gatsby는 정적 사이트 생성과 동적 서버 사이드 렌더링을 결합해 SEO를 최적화하는 데 유리한 플랫폼이다. 아래는 Gatsby의 SEO 관련 주요 특징이다. 정적 사이트 생성(Static Site Generation, SSG): 정적 사이트를 생성하므로, 모든 페이지의 HTML이 미리 생성된다. 이는 검색 엔진 크롤러가 콘텐츠를 쉽게 찾고 인덱싱할 수 있도록 한다. 서버사이드 렌더링(Server-Side Rendering, SSR) 지원: 동적 콘텐츠에 대한 서버사이드 렌더링을 지원한다. 이를 통해 초기 로딩 속도를 개선하고, 소셜 미디어 미리보기와 같은 기능을 구현할 수 있다. 예상 로딩(Prefetching): 링크가 마우스를 올리거나 포커스를 받았을 때 미리 데이터를 가져와..
· Gatsby
Gatsby는 사이트 내에서 마크다운 파일로 페이지 생성을 할 수 있다. 마크다운 파일을 읽고 이해하기 위해 플러그인을 추가하고, 그 파일로부터 페이지를 자동 생성한다. 파일 시스템으로부터 Gatsby로 파일 읽어오기 아래 플러그인을 사용해 파일을 읽고 Gatsby가 GraphQL 데이터 레이어에 파일 노드를 생성하도록 할 수 있다. npm install gatsby-source-filesystem 개츠비 설정 파일인 gatsby-config.js를 열어 gatsby-source-filesystem 플러그인을 추가한다. path 옵션은 파일을 검색할 디렉토리를 설정하는 방법이다. // gatsby-config.js module.exports = { plugins: [ { resolve: `gatsby-s..
· Next.js
CRUD, 몽고DB 카버차트는 위 사진처럼 스포티파이 API를 통해 가져온 음반 정보, 내가 임의로 추가한 텍스트를 합쳐 하나의 포스트로 표시한다. 그런데 데이터를 추가할수록 이를 지속적으로 관리할 수 있는 방식, 그러니까 특정 데이터베이스에 포스트를 업로드하고, 가져오고, 수정하고, 삭제하는 로직이 필요하다는 생각이 들었다. 이를 흔히 CRUD(Create, Read, Update, Delete)라고 한다. 몽고DB는 데이터를 JSON 구조로 저장해 사용자의 직관적인 이해를 돕고, 다른 데이터베이스에 비해 사용 방법이 쉽다. 무료 플랜의 경우 저장된 데이터를 불러오는 속도가 다소 느리긴 하지만, 사용하지 못할 정도는 아니다. MongoDB: 애플리케이션 데이터 플랫폼 업계 최고의 최신 데이터베이스를 토..
· Next.js
다음 링크에 Next.js에서 다이나믹 라우트를 처리하는 방법이 자세하게 설명되어 있다. Routing: Dynamic Routes | Next.js Using Pages Router Features available in /pages nextjs.org 예를 들어, 블로그 사이트는 pages/blog/[slug]와 같은 라우트 페이지를 포함할 수 있다. 여기에서 [slug]는 블로그 포스트에 대한 다이나믹 세그먼트(데이터가 표시할 수 있는 형식으로 변환된 형태)이다. [slug]는 원하는 이름으로 얼마든지 변경 가능하다. 이 프로젝트에서는 음악 장르 페이지에 해당하므로 이름을 [genre]로 설정했다. 다이나믹 세그먼트에 해당하는 컴포넌트에서는 다음과 같은 방식으로 경로의 이름을 가져와 이용할 수 있다..
· Next.js
다음 링크에서는 전세계의 각종 날씨 정보 API를 무료로 제공한다. 사이트에 가입하고 나서 무료 플랜을 신청하면 개인별 API 키가 생성되는데, 해당 정보로 API를 호출해 원하는 날씨 정보를 가져올 수 있다. Current weather data - OpenWeatherMap openweathermap.org async & await 문법으로 API를 비동기 처리했다. JSON 형식으로 서울의 현재 온도 및 날씨 아이콘 정보를 한국어로 가져온 뒤, weather라는 상태 변수에 해당 데이터를 객체로 저장했다. 참고로 API 키는 원래 긴 문자열 형태지만, 보안 문제로 줄임 표시했다. export const fetchData = async (setWeather: React.Dispatch) => { tr..
· Next.js
시계 컴포넌트 사이트 상단바에 현재 시각을 실시간으로 표시하는 시계 기능을 넣었다. 시계는 1초마다 렌더링을 발생시켜 주어진 함수에 의해 현재 시각을 체크한다. 그런데 이 부분이 Next.js의 서버 사이드 렌더링과 충돌하면서 런타임 에러가 발생했다. 브라우저에서만 동작하는 서드파티 라이브러리나 모듈을 사용할 때 종종 이런 이슈가 발생된다고 한다. 이 경우 서버 사이드 렌더링을 직접 해제해야만 한다. 컴포넌트가 window 객체 또는 로컬 스토리지 속성에 접근해야 한다면 서버 사이드 렌더링이 불필요하다. 프로젝트에서 서버 사이드 렌더링을 사용할지 여부는 개인의 선호도 문제이다. export default function Clock() { const language = useContext(LanguageC..
카버
카버의 코딩일기