분류 전체보기 113

TypeScript 정적 타이핑의 장단점 정리

이번에 타입스크립트를 사용해서 Kanban 보드 컴포넌트를 수정했다. 처음엔 타입 오류 때문에 머리가 좀 아팠지만, 해결하고 나니 코드가 더 안정적으로 변한 느낌이 들었다. 이 과정을 기록해두고, 정적 타이핑의 장단점을 정리해보고자 한다. 문제 :  타입 불일치KanbanColumn 컴포넌트에서 버튼 이벤트 핸들러(onAddTodo, onRemoveColumn, onEditColumn)를 부모 컴포넌트로 전달하려고 했는데, 타입스크립트에서 오류가 발생했다. 오류 메시지는 다음과 같았다:'(col: Column) => void' 형식은 '() => void' 형식에 할당할 수 없습니다.대상 서명이 너무 적은 인수를 제공합니다. 1 이상이 필요하지만 0을(를) 받았습니다.ts(2322) 원인을 살펴보니, K..

TypeScript 2025.02.23

Zustand로 모드 전환 로직 최적화

Kanban 보드에서 editMode, deleteMode, errorMode를 버튼(✏️, 🗑️, ⚠️)으로 전환할 때, editMode가 켜진 상태에서 다른 모드를 클릭하면 editMode가 꺼지지 않고 유지되었다. 또한, deleteMode나 errorMode에서 다른 모드로 전환할 때 editMode가 불필요하게 켜지는 현상이 발생했다.원인 분석Zustand 스토어의 toggleEditMode, toggleDeleteMode, toggleErrorMode 함수는 개별적으로 상태를 토글하도록 설계되었으나, KanbanHeader의 onClick 핸들러에서 다른 모드를 명시적으로 끄는 로직이 불완전했다. 예를 들어, toggleDeleteMode 호출 시 if (errorMode || editMod..

Zustand 2025.02.23

Next.js에서 Zustand와 Supabase를 사용할 때 새로고침 시 상태가 초기화되는 문제 해결

React에서 상태를 관리할 때 useState나 useStore(Zustand)를 사용할 경우, 브라우저 새로고침 후 상태가 초기화되는 문제가 발생할 수 있다. 특히, Supabase와 같은 외부 데이터베이스에서 데이터를 불러와 Zustand에 저장한 후 사용할 때, 새로고침을 하면 UI에는 데이터가 없지만, Supabase에서 데이터를 다시 불러와야 하는 상황이 반복될 수 있다.이 문제는 클라이언트 사이드에서만 데이터를 가져오도록 설정했기 때문에 발생했다. Next.js의 App Router에서는 클라이언트 컴포넌트가 처음 렌더링될 때 상태가 초기화되며, 서버에서 데이터를 미리 가져오지 않으면 클라이언트가 비어 있는 상태로 시작하게 된다.발생한 문제Zustand를 이용해 보드 목록을 상태로 저장하고 ..

Zustand 2025.02.20

Zustand로 React 상태 업데이트 지연 문제 해결하기

React에서 상태를 관리할 때 useState를 사용하면 비동기 업데이트로 인해 최신 값이 반영되지 않는 경우가 있다. 특히, 디바운싱을 적용한 비밀번호 입력에서 setState가 지연되면서 서버로 전송되는 값이 최신 값이 아니라 이전 값(3글자)만 전송되는 문제가 발생했다. 처음에는 setTimeout을 추가해서 상태가 업데이트될 시간을 주려고 했지만, 여전히 최신 값을 보장하지 못했다. 그래서 Zustand를 활용하여 전역 상태로 관리하면 해결될 것 같았다. 하지만 처음 시도한 방식으로는 상태가 여전히 클로저에 묶여 있고, 제출 시점에서 최신 상태를 반영하지 못하는 문제가 있었다.  비밀번호 입력 로직에서 useState를 사용하면 다음과 같은 문제가 발생한다.setPassword(val) 호출 시..

Zustand 2025.02.10

axiosInstance 전역상태에서 토큰 만료시 401 오류 처리

API 호출을 했는데 자꾸 401 에러가 떴다. 혹시 토큰이 만료됐나 싶어서 로컬 스토리지를 확인했더니 예전에 쓰던 값 그대로였다.만료된 토큰을 계속 사용해서 서버가 신뢰하지 못한 것이다. 그래서 응답 인터셉터를 수정했다. 401 에러가 발생하면 로컬 스토리지에서 accessToken을 삭제하고 로그인 페이지로 리다이렉트하도록 코드를 추가했다. 이렇게 처리하고 다시 테스트해보니, 만료된 토큰으로 인해 401 에러가 발생해도 자동으로 로그아웃되면서 로그인 페이지로 이동했다. import axios from "axios";const axiosInstance = axios.create({ baseURL: "http://localhost:8383", withCredentials: true,});axiosIn..

Axios 2025.02.10

GSAP 스크롤 후 페이드인 처리

이미지를 클릭했을 때, 해당 이미지가 화면 중앙에 오도록 스크롤하고, 그 뒤 부드럽게 페이드인하는 기능을 만들고 싶었다.처음에는 window.scrollTo({ behavior: "smooth" }) 정도면 되지 않을까 했는데, smooth 스크롤이 브라우저 기본 기능이라서 지속 시간을 세밀하게 제어하기가 쉽지 않았다.그래서 GSAP의 ScrollToPlugin을 사용하기로 했다. 이걸 쓰면 원하는 시간(0.2초, 0.3초 등)을 직접 지정할 수 있었다. 그러나 또 다른 고민은 사용자에게 스크롤 애니메이션 과정을 아예 안 보이게 하고 싶다는 것이었다. 그래서 스크롤은 즉시 이동(애니메이션 없음)으로 처리하고, 10ms 정도 뒤에 페이드인 애니메이션을 실행했다.  간단한 예시 코드Home.tsx (일부 발..

GSAP 2025.02.05

Zustand로 글로벌 상태 관리 도입기

최근 프로젝트에서 헤더에 있는 플러스 버튼으로 그리드 레이아웃(예: 9열, 3열, 1열)을 전환하는 기능을 구현하려고 했다.처음에는 Home 컴포넌트 내부 상태만 바꾸면 되겠다고 생각해서 Home 컴포넌트에서 gridState라는 useState를 만들어 관리했는데, 막상 헤더에서 plus 버튼을 누르면 이 상태가 업데이트되지 않아 그리드 전환이 되지 않았다.처음엔 Prop Drilling으로 해결할까 했지만 구조가 복잡해질 것 같았다. 차라리 글로벌 상태 관리 라이브러리를 써보자 싶어서 Zustand를 도입했다. 써보니 Redux처럼 많은 보일러플레이트가 필요 없고, 훨씬 간단했다.대략적인 구현 과정은 이랬다:useGridStore.ts 파일을 만들고, gridState(예: "grid9", "grid..

Zustand 2025.02.05

Next.js에서 GSAP 최적화하기: 중앙집중화로 성능 개선

최근 Next.js 프로젝트에서 GSAP를 활용해 섹션마다 애니메이션을 적용했는데, 모바일에서 로딩이 너무 느려서 LCP가 30초 이상 찍히기도 하고, Hydration Error까지 발생했다. 다음 버전으로 마이그레이션을 했더니 어느 정도 성능은 좋아졌지만, 여전히 스크롤 트리거가 제대로 동작하지 않거나, 불필요하게 렌더링이 많이 일어나는 문제가 있었다. 특히 섹션별로 GSAP 초기화를 각각 따로 두면서 “use client”를 남발하다 보니 코드가 복잡해지고 성능이 떨어진 느낌이었다. 해결 방안처음에는 애니메이션 초기화만 따로 떼어 놓으면 되지 않을까 하고 단순하게 생각했다. 그런데 막상 적용해보니 각 컴포넌트에서 불필요한 “use client” 선언이 많고, ScrollTrigger를 초기화할 때마..

Next.js 2025.01.22

Next.js 15에서 발생한 Hydration 오류와 해결 과정

Next.js 15로 업데이트한 뒤, 예상치 못한 Hydration 오류가 발생했다. typeof window !== 'undefined' 같은 조건문을 사용하는 코드에서 특히 문제가 심했다. SSR과 CSR에서 HTML이 다르게 렌더링되면서 React가 이를 감지하고 경고를 띄웠다. 해결하기 위해 여러 가지 시도를 해봤지만, 결국 Next.js 14와 React 18.2.0으로 다운그레이드하는 것이 가장 안정적인 방법이었다.Hydration 오류의 주요 원인typeof window !== 'undefined'** 사용**: Next.js 15에서는 SSR과 CSR에서 typeof window 조건문이 불일치를 일으킬 가능성이 높아졌다.스타일 동적 변경: GSAP, Swiper 같은 라이브러리들이 CSR..

Next.js 2025.01.20

Next.js 14: Pages Router에서 App Router로 마이그레이션하기

1. App Router로 변경해야 하는 이유Next.js 14가 나오면서 공식 문서에서도 App Router를 권장했다. 기존 pages/ 폴더 기반의 Pages Router는 점차 유지보수 대상에서 밀려나고 있는 상황이었다.이번 기회에 프로젝트를 App Router로 마이그레이션하면서 변경해야 할 부분을 정리했다.주요 장점은 다음과 같았다.서버 컴포넌트 지원으로 클라이언트에서 불필요한 JS 실행을 줄일 수 있었다.레이아웃을 더 직관적으로 관리할 수 있었다.파일 기반 라우팅이 더욱 강력해졌다.TypeScript 없이도 사용 가능했다.대부분의 자료가 TypeScript 기반이었지만, 자바스크립트만으로도 App Router를 충분히 활용할 수 있었다.이번 마이그레이션 과정도 TS 없이 JavaScript만..

Next.js 2025.01.20