react
[Next.js] dnd-kit을 활용한 칸반(Kanban) 보드 드래그 앤 드롭 구현
[Next.js] dnd-kit을 활용한 칸반(Kanban) 보드 드래그 앤 드롭 구현
2025.03.18일반적으로 칸반 보드는 드래그 앤 드롭을 통해 컬럼이나 태스크 카드의 순서를 자유롭게 변경할 수 있다. 이러한 드래그 앤 드롭 상호작용은 dnd-kit 이라는 라이브러리에서 제공하는 Sortable 프리셋을 이용하면 더 쉽게 구현할 수 있다. dnd-kit은 코어 크기가 10kb 정도로 가볍고 외부 의존성이 없는 장점이 있다. 드래그 제한, 애니메이션, 충돌 감지 등을 커스터마이징 할 수도 있다. dnd-kit을 이용해 칸반 보드를 구현하면서 비교적 까다롭다고 느꼈던 부분들을 정리해 봤다. 코드는 아래 레포지토리에서 확인할 수 있다.레포지토리: https://github.com/romantech/simple-kanban데모 페이지: https://kanban.romantech.net 칸반 데이터 모..
[UI] Shadcn DropdownMenu에서 Dialog 자동 닫힘 문제 해결
[UI] Shadcn DropdownMenu에서 Dialog 자동 닫힘 문제 해결
2025.03.09Shadcn의 드롭다운(Dropdown)은 특정 동작이나 기능 등을 Popover 형태로 표시하는 컴포넌트다. 드롭다운 메뉴 아이템(DropdownMenuItem)을 클릭했을 때 다이얼로그(혹은 AlertDialog)를 띄우려는 의도로 메뉴 아이템의 자식으로 다이얼로그를 추가할 수 있다. 하지만 이렇게 작성하면 다이얼로그가 제대로 열리지 않는다. 메뉴 열기 {/* ... */} ; Radix의 메뉴 아이템은 클릭했을 때 드롭다운이 자동으로 닫히도록 설계되어 있다. 때문에 다이얼로그를 띄우는 메뉴 아이템을 클릭하면, 드롭다운이 닫히는 기본 동작에 의해 다이얼로그가 열리지 마자 닫히는 문제가 발생한다. 위 문제로 StackOverFlow를 찾아보면 Dr..
[React] 리액트 19 업데이트 내용 톺아보기
[React] 리액트 19 업데이트 내용 톺아보기
2025.02.082024년 12월 React 19의 stable 버전이 출시됐다. 리액트 공식 블로그를 참고해서 React 19의 주요 변경 사항을 정리해 봤다. 새롭게 선보인 훅은 각종 문서와 예제를 참고해서 이해하기 쉽도록 부연 설명을 덧붙였다. 공식문서에 기존 사용자를 위한 마이그레이션 가이드도 자세하게 나와있으니 참고하자. useTransitionuseTransition은 주로 무거운 작업의 상태 업데이트를 낮은 우선순위로 지정하여 UI 블로킹을 방지할 때 사용한다. React 18 버전까지 startTransition 콜백은 항상 동기적이어야 하는 제약이 있었다. 때문에 콜백 안에서 비동기 호출 같은 작업을 수행할 수 없었다. React 19부턴 startTransition 콜백 안에서 비동기 처리도 가능해졌..
[Next.js] Dynamic Routes 다이나믹 라우트
[Next.js] Dynamic Routes 다이나믹 라우트
2025.01.31TL;DR[slug] : 단일 경로 세그먼트 포착[...slug] : 다중 경로 세그먼트 포착(Catch-All)[[...slug]] : 루트 경로를 포함한 모든 경로를 선택적으로 포착(Optional Catch-All) Dynamic Segments정확한 세그먼트 이름을 미리 알 수 없을 때 폴더 이름을 대괄호로 감싸면 다이나믹 세그먼트로 작동. 세그먼트 이름은 layout, page 또는 route 파일에서 params 프롭으로 값 조회 가능. RouteURL ExampleParamsapp/blog/[slug]/page.js/blog/a{ slug: 'a' }app/blog/[slug]/page.js/blog/b{ slug: 'b' }루트 경로(blog/)에 페이지 없으면 접근 불가. Catch-..
[Next.js] App Router 공식 튜토리얼 톺아보기
[Next.js] App Router 공식 튜토리얼 톺아보기
2025.01.30Next.js에서 제공하는 Learn Next.js App Router 튜토리얼을 부연 설명과 함께 한국어로 정리해 봤다. 공식 가이드는 총 16개 챕터로 구성되어 있지만, 이번 포스팅에선 프로젝트 세팅을 다루는 챕터 1과 CSS 스타일링 방법을 설명하는 챕터 2는 생략했다. Optimizing Fonts and ImagesCumulative Layout Shift(CLS, 누적 레이아웃 이동)는 구글이 웹사이트의 성능과 사용자 경험을 평가하는 데 사용하는 지표로, 페이지 로드 중 레이아웃 이동으로 인해 발생하는 사용자 경험의 불편함을 측정한다. 예를 들어, 브라우저가 폴백(fallback) 폰트나 시스템 폰트로 텍스트를 먼저 렌더링 한 뒤 사용자 지정 폰트로 교체할 때 텍스트 크기, 간격 또는 레이아..
[React] 리액트의 올바른 useEffect 사용팁
[React] 리액트의 올바른 useEffect 사용팁
2025.01.21리액트의 useEffect는 데이터 가져오기, 구독 관리, DOM 업데이트, 사이드 이펙트 처리 등 다양한 작업에 사용된다. 그러나 useEffect를 과도하게 사용하면 성능 저하, 불필요한 렌더링, 디버깅의 복잡성 같은 문제가 발생할 수 있다. "Leave useEffect Alone!" 라는 가이드 글을 참고하여 올바른 useEffect 사용법에 대한 추가 설명을 덧붙여서 정리해 봤다. 경쟁 상태(Race Condition) ⭐경쟁 상태는 여러 비동기 작업이 동시에 실행될 때, 실행 순서나 결과가 예측하지 않은 방식으로 작동하는 현상을 가리킨다. 아래 코드에서 버튼을 여러 번 클릭하면 counter 값이 증가하고, 각 요청은 랜덤한 시간만큼 대기한 후 response 상태를 업데이트한다. 하지만 이..
[React] 리액트 코드를 개선할 수 있는 4가지 팁
[React] 리액트 코드를 개선할 수 있는 4가지 팁
2024.10.28TLDR이벤트 핸들러에 커링 활용컴포넌트 책임 분리조건문 대신 객체 map 사용React 라이프사이클 외부에 독립적인 변수 배치 4 React Tips1. 커링 활용user 상태는 name, surname, address 3개 속성을 가지며, 이에 대응하는 3개의 input 필드가 필요하다. 아래 코드에선 각 필드를 처리하기 위해 별도의 핸들러를 각각 만들어서 사용하고 있지만, 이 핸들러들은 value가 할달될 속성 이름만 다를 뿐 나머지 로직이 동일하기 때문에 코드 중복이 발생하고 있다.export default function App() { const [user, setUser] = useState({ name: "", surname: "", address: "", }); co..
[DevTools] ESLint 9 Flat Config + Prettier 설정 (TypeScript, React)
[DevTools] ESLint 9 Flat Config + Prettier 설정 (TypeScript, React)
2024.06.30Flat ConfigESLint 8.21.0 버전부터 구성 파일에 큰 변화가 생겼다. 기존 .eslintrc 파일 대신 플랫 구성(Flat Config)을 사용하는 eslint.config.js 형식이 새로 도입된 것. 플랫 구성은 extends나 overrides 같은 계층 구조없이 각 구성을 이루는 객체들을 포함한 1차원 배열로 표현한다. 이를 통해 규칙을 세분화해야 하는 상황에서 더 유연하게 대응할 수 있게 됐다. e.g., 구성 객체 1-자바스크립트 규칙, 구성 객체 2-타입스크립트 규칙 필요한 플러그인은 직접 import 한 후 사용하는 방식으로 변경돼서 종속성을 더 명확하게 관리할 수 있다.// eslint.config.js 파일 예시import eslint from '@eslint/js';i..
[Next.js] App Router / 서버 컴포넌트 주요 내용 정리
[Next.js] App Router / 서버 컴포넌트 주요 내용 정리
2024.06.01App Router vs Page Router기능앱 라우터페이지 라우터라우팅 타입서버 중심클라이언트 사이드서버 컴포넌트 지원OX복잡도더 복잡함더 간단함성능더 좋음더 나쁨유연성더 유연함덜 유연함파일 기반 라우팅중첩 폴더를 사용해 라우트 정의파일이 직접 라우트를 나타냄컴포넌트 기본적으로 서버 컴포넌트기본적으로 클라이언트 컴포넌트데이터 페칭fetch 함수 사용getServerSideProps, getStaticProps, getInitialProps 사용레이아웃레이아웃 중첩 / 동적 레이아웃정적 레이아웃동적 라우트지원하지만 문법 다름Link 컴포넌트로 지원우선순위페이지 라우터보다 우선앱 라우트가 없을 경우 대체 서버 컴포넌트Next.js 버전 13~부터 제공하는 App Router를 사용하면 서버 컴포넌트가 ..
[React] 틱택토(Tic-Tac-Toe) 게임 주요 로직 톺아보기
[React] 틱택토(Tic-Tac-Toe) 게임 주요 로직 톺아보기
2024.05.30틱택토 소개틱택토는 2명의 플레이어가 자신의 기호(X, O) 3개를 가로, 세로, 대각선으로 연속해서 놓이도록 하는 보드 게임이다. 게임은 주로 3x3 격자 보드에서 진행된다. 플레이어는 번갈아가면서 자신의 기호를 놓고, 한 칸엔 한 개의 기호만 놓을 수 있다. 모든 칸에 기호를 놓았지만 어느 한쪽도 연속적인 세 개의 기호를 배열하지 못하면 게임은 무승부로 끝난다(무승부가 많은 게임). 승리 조건 체크틱택토는 행렬로 이뤄진 2차원 보드에서 진행하지만, 1차원 배열로 관리하면 각 칸을 단일 인덱스로 접근할 수 있기 때문에 데이터를 더 수월하게 관리할 수 있다. 게임 로직을 구현할 때도 인덱스 계산을 단순화시켜 코드의 복잡성을 줄이는 데 도움이 된다. 또한, 1차원 배열은 그리드 스타일을 이용해 2차원 보..
[React] 리액트에서 setTimeout 더 편하게 쓰기
[React] 리액트에서 setTimeout 더 편하게 쓰기
2024.05.28React에서 setTimeout 같은 타이머 API를 사용할 때 컴포넌트의 생명주기를 고려하지 않으면 메모리 누수나 예기치 않은 예외가 발생할 수 있다. 예를 들어 타이머를 설정한 후 컴포넌트가 언마운트돼도 타이머는 여전히 실행되고, 이후 타이머 콜백에서 언마운트된 컴포넌트의 상태를 업데이트하려고 하면 에러가 발생할 수 있다. 위 같은 상황을 방지하기 위해 useEffect의 클린업 함수에 타이머 해제 로직을 추가한다. 하지만 한 컴포넌트에서 여러 타이머를 관리해야 한다면 메모리 누수 뿐만 아니라 타이머를 관리하기 위한 로직 때문에 컴포넌트의 복잡성이 높아질 수 있다. 만약 별도의 커스텀 훅에서 타이머를 관리하고, 커스텀 훅이 언마운트 될 때 모든 타이머를 자동으로 해제한다면 해당 훅을 사용하는 곳에선..
[React] 크롬 확장 프로그램 개발 배경 지식 및 튜토리얼
[React] 크롬 확장 프로그램 개발 배경 지식 및 튜토리얼
2024.05.28크롬 확장기능 주요 기능사용자 인터페이스 사용자화 : 브라우저 툴바에 버튼 추가, 사용자 정의 팝업/오버레이 생성 등콘텐츠 스크립트 : 웹페이지에 직접 스크립트를 삽입하여 DOM 조작 가능백그라운드 스크립트 : 브라우저를 사용하는 동안 지속적으로 실행돼서 필요한 기능 제공API 접근 : 북마크/탭/윈도우 관리, 히스토리 조작 등 브라우저의 다양한 영역 접근 가능🔍 탭 이동, capture, zoom 등 다양한 방식으로 제어 가능메시징 시스템 : 확장 기능의 다른 컴포넌트 혹은 웹페이지와 메시지 교환 가능웹 요청 조작 : 네트워크 요청 가로채기, 광고 차단, 프라이버시 보호, 웹 트래픽 관리 등🔍 chrome.webRequest API로 http 요청을 가로채거나 request header 수정 가능사..