FrontEnd Develop 69

TODOMVC : 완성 후의 리팩토링

1. 초벌 분리의 시작: 하나의 거대한 컴포넌트처음에는 TodoPage.tsx 내부에 상태 관리, 탭 UI, 입력 폼, 리스트 렌더링까지 모두 들어있는 구조였다. 작성 당시에는 직관적으로 빠르게 구현할 수 있었지만, 다음과 같은 문제점들이 눈에 띄었다.한 파일에 너무 많은 책임이 집중되어 있었다.컴포넌트 재사용이 어려웠다.테스트 및 유지보수가 어려워질 조짐이 보였다.따라서 다음과 같은 기준을 두고 리팩토링을 시작했다.2. 단계적 분리 전략2-1. Atomic 컴포넌트 분리공통적으로 쓰일 수 있는 Input과 Button을 components/atomic/ 디렉토리로 분리했다.components/ atomic/ Input.tsx Button.tsx이는 UI 재사용성과 일관된 스타일 적용을 위한..

비동기처리의 이해 : Promise, async/await 그리고 MicroTask?

자바스크립트는 단일 스레드 기반 언어지만, 웹 API와 이벤트 루프를 통해 비동기 처리를 지원합니다. 이 글에서는 Promise.then(), async/await, setTimeout() 등이 함께 혼재될 때의 실행 순서와 내부 구조를 이해하기 쉽게 정리합니다.1. JavaScript의 실행 환경 : 이벤트 루프 구조자바스크립트는 다음과 같은 실행 큐를 기반으로 동작합니다:Call Stack: 현재 실행 중인 코드Microtask Queue: 우선순위 높은 비동기 작업 → Promise.then(), await, queueMicrotask() 등Macrotask Queue: 일반적인 비동기 → setTimeout(), setInterval() 등실행 순서:동기 코드 (call stack) 먼저 실행Mi..

FrontEnd Develop 2025.05.19

Github 이해하기 #1. 두 사람의 브랜치 병합 협업

이번 글에서는 Git 협업에서 자주 마주하게 되는 브랜치 병합 과정을, 두 명의 개발자 Jessica와 John의 사례를 통해 단계별로 설명합니다. 이 글은 Git의 기본 구조를 이해하고자 하는 분에게 적합합니다.상황 가정John과 Jessica는 동일한 원격 저장소(origin)에서 각각 작업을 진행합니다.둘 다 master 브랜치를 기준으로 작업을 시작했으며, 각자의 로컬에서 feature를 개발한 후, 이를 다시 master로 병합하려고 합니다.1. 원격 저장소를 클론두 사람은 각각 다음과 같이 원격 저장소를 클론하여 작업을 시작합니다:$ git clone git@host:simplegit.git이때 로컬에는 다음과 같은 브랜치가 생성됩니다:master (로컬 작업 브랜치)origin/master..

FrontEnd Develop 2025.05.19

UseState 그냥 쓰지말고 알고쓰자!

UseState DeepDiveINTRO. 상태값 변경시 리렌더링 발생useState에서 반환된 배열의 두번째 값인 setter 함수를 호출하면 상태 값을 변경할 수 있고, 상태 값이 변경되면 해당 컴포넌트는 다시 렌더링됩니다.=> 컴포넌트가 마운트되었을 때는, 기본적으로 useState(초기값)에서 인자로 전달된 값을 상태의 초기값으로 사용합니다. 하지만 이후 setter 함수에 의해 상태의 값이 변경되었다면, 다음 렌더링에서는 그 상태를 유지합니다.setState 호출 => 상태 변경 => 리렌더링(변경된 상태값 사용)THEME #1. setState는 비동기로 동작한다. (정확히 비동기함수다 X)useState의 setter 함수를 호출한 이후 바로 다음 줄에서 해당 state값을 참조하면 아직 바..

FrontEnd Develop 2025.05.07

STT 라우팅과 비동기 처리 분리하기: 실전 리팩토링 사례

"2025년 5월 4일, 라우팅 흐름부터 API 처리까지, 실전 개발 중 맞닥뜨린 문제들과 그 해결 과정" ✨ 문제의 시작: 비동기 처리와 라우팅이 엉킨다처음엔 단순한 흐름이라고 생각했다. 기획자와 논의한 유저 플로우:사용자가 수업 영상 파일을 업로드하고 "다음" 버튼을 누른다.노트를 생성한다 (createNote).STT 변환을 시작한다 (createSTT).STT가 끝나면 다음 페이지로 router.push() 한다.다음 페이지에서 STT 결과를 기반으로 요약문을 생성한다.⚠️ 기존 코드 구조 (문제 있는 구조)const handleNoteNextBtn = async () => { const createdNote = await createNote(folderId, { title: noteName }..

타입스크립트(자바스크립트) 배열 반복(iteration) 메서드 정리

프론트엔드 개발에서 배열을 다룰 때 자주 사용하는 반복(iteration) 메서드들에 대해 정리해봅니다. map, filter, forEach, find, reduce 등은 모두 배열의 각 요소를 순회하며 무언가를 처리하는 함수형 도구입니다.✅ 1. map()배열의 각 요소를 **변형(transform)**하여 새로운 배열을 생성✅ 리턴값 필요: 각 요소를 어떻게 바꿀지 return 필수const numbers = [1, 2, 3];const doubled = numbers.map((n) => n * 2); // [2, 4, 6]원본 배열 유지됨JSX에서도 아주 자주 쓰임{todoList.map((todo) => ( {todo.text}))}✅ 2. filter()조건에 맞는 요소만 걸러내서 새 배열 ..

TypeScript의 객체 타입 지정에 편리한 내장 Record 유틸리티 타입

TypeScript에서는 객체의 타입을 명시할 때 보통 아래처럼 key-value 형태로 정의합니다:const user: { name: string; age: number } = { name: 'Alice', age: 30,};하지만 더 유연하고 깔끔하게 작성할 수 있는 유틸리티 타입이 있습니다. 그중 대표적인 것이 바로 **Record**입니다.Record란?"키가 K 타입이고, 값이 V 타입인 객체를 정의한다"는 의미입니다.Record 문자열 키와 문자열 값const colorMap: Record = { primary: 'blue', danger: 'red', success: 'green',}; 위는 아래와 동일한 의미를 가집니다.const colorMap: { [key: string]: s..

Tailwind 기반 버튼 컴포넌트 재활용하기

재활용을 왜하는가?React 프로젝트를 진행하다 보면 버튼과 같은 컴포넌트들을 반복해서 만들게 됩니다. 그때마다 className을 복붙하고 색깔을 바꾸다 보면 코드가 지저분해지고, 유지보수도 힘들어집니다. 이번 글에서는 Tailwind CSS + TypeScript 조합으로 깔끔하고 재사용 가능한 버튼 컴포넌트를 만들어보는 방법을 공유합니다.1. 기본 Button 컴포넌트 만들기먼저 가장 기본이 되는 버튼 컴포넌트를 Button.tsx로 만들겠습니다.import { ButtonHTMLAttributes } from 'react';interface ButtonProps extends ButtonHTMLAttributes { variant?: 'primary' | 'danger' | 'black'; f..

Zustand X Generic 심층분석.

Zustand create 완전 정복을 위하여..늘 context API로 전역상태 관리를 활용하던 내가 , zustand 공식문서를 읽어보며 zustand 활용법을 공부했다. zustand에는 Generic type으로 선언된 함수가 매우많아서 Generic 관련 내용 또한 매우 중요하다고 판단하여 같이 콜라보하여 공부했다.1. 제네릭이란 무엇인가?TypeScript에서 흔히 보이는 함수 형태는 제네릭(Generic) 문법입니다.function identity(value: T): T { return value;}identity('hello'); // ✉️ T = string → 매개변수도, 리턴값도 string즉, T라는 타입은 함수 선언부에서 고정하지 않고, 호출할 때 지정할 수 있는 타입 매개변수..

Props를 단순히 부모 - 자식 관계로만 치부할지말자.

중복된 여러 코드가 보기 싫다에서 탄생된 것이 props다.회원가입 form을 예시로, 아이디, 비밀번호, 뭐 등등 입력하는 칸거의 완전 똑같이 생겼는데 이걸 굳이 3줄 겹치는 내용을 적어야한다면 그것은 비효율적이겠다.import React, { useState } from 'react';export default function SignupForm() { const [id, setId] = useState(''); const [pw, setPw] = useState(''); return ( 아이디 setId(e.target.value)} className="border p-2 rounded" /> ..