티스토리 뷰
본 포스팅은 프로젝트 회고를 목적으로 작성되었습니다.
프로젝트 결정 계기
이번 프로젝트는 <실전 TypeScript와 고급 웹 개발>을 주제로 한 개인 학습 및 경험 확정을 목표로 진행되었습니다🫨🫨
본래 남은 5주간 블로그를 직접 개발할 계획이었지만, Gastby와 같은 템플릿들을 살펴본 결과 생각보다 제공되는 기능이 풍부해, 제가 직접 구현하고 학습할 요소가 적다는 결론에 이르렀습니다.
이에 따라 블로그 개발에 바로 들어가기보다는, TypeScript에 대한 이해도를 한층 더 높일 수 있는 다른 프로젝트를 먼저 진행하기로 했습니다.
React 순차적 계산기: TypeScript로 마이그레이션
본 포스팅은 프로젝트 회고를 목적으로 작성되었습니다.프로젝트 결정 계기 본 프로젝트는 학교에서 진행하는 진로탐색학점제의 일환으로, [실전 TypeScript와 고급 웹 개발]이란 주제로 진행
404minda.tistory.com
앞선 순차적 계산기 프로젝트에서, 타입 좁히기와 타입 넓히기 개념에 대한 부족한 이해로 마이그레이션 과정이 생각보다 오래 걸렸던 경험이 있습니다. 이를 계기로 TypeScript의 타입 시스템을 보다 깊이 이해하고, 특히 타입 좁히기 개념을 실제 프로젝트에 적용해보고자 하는 필요성을 느꼈습니다.
또한, 프리코스를 통해 학습한 모듈 설계와 클린 코드를 바탕으로 둔 리팩토링 경험을 이번 프로젝트에 녹여내면 가독성 있는 코드와 확장 가능한 설계를 만들 수 있을 것이라는 자신감도 있었습니다💪🏻
이러한 배경에서, 타입 좁히기와 모듈 설계를 직접 실습할 수 있는 프로젝트로 투두리스트 애플리케이션을 선택했습니다. 비교적 간단한 기능을 포함하면서도, 상태 관리와 조건부 로직이 많아 타입 좁히기를 충분히 연습할 수 있는 주제로 적합하다고 판단했습니다. 또한, 투두리스트는 UI 설계와 UX에 있어서도 가시적인 성과를 빠르게 확인할 수 있으니 이해하기 쉬운 프로젝트로 판단했습니다.
선행 연구
이번 프로젝트를 진행하기 전, 우아한테크코스 프리코스 과정에서 다양한 개발 경험을 쌓으며 모듈 설계와 클린 코드에 기반을 둔 리팩토링 방법에 대해 학습했습니다. 이 과정에서 기능 단위로 코드를 분리하는 설계 방식과 리팩토링을 통해 가독성과 유지보수성을 개선하는 방법을 배울 수 있었습니다.
[프론트엔드 7기] 우아한테크코스 - 정규표현식과 문자열 계산기 회고
본 포스팅은 우아한테크코스 7기 프론트엔드 전형 지원에 대한 회고록입니다. 첫 번째 과제는 문자열 덧셈에서 숫자를 추출해 더하는 프로그램을 구현하는 것이었습니다. 기능 요구 사항은
404minda.tistory.com
[프론트엔드 7기] 우아한프리코스 - 삼항연산자와 자동차 경주 회고
본 포스팅은 우아한테크코스 7기 프론트엔드 전형 지원에 대한 회고록입니다. 이번 주 과제는 자동차 경주 게임 제작입니다. 사용자의 입력을 받아 게임을 진행하고, 최종 우승자를 선정하는
404minda.tistory.com
[프론트엔드 7기] 우아한프리코스 - 모듈설계(DDD)를 곁들인 로또
본 포스팅은 우아한테크코스 7기 프론트엔드 전형 지원에 대한 회고록입니다. 이번 주 과제는 로또 발매기 제작이었습니다. 구입 금액에 따라 로또를 발행하고, 당첨 내역과 수익률을 출력하
404minda.tistory.com
[프론트엔드 7기] 우아한프리코스 - 전략패턴(Strategy Pattern)을 이용한 우아한 편의점
본 포스팅은 우아한테크코스 7기 프론트엔드 전형 지원에 대한 회고록입니다. 4주차 과제는 편의점 결제 시스템을 구현하는 것이었습니다. 구매자의 할인 혜택과 재고 상황을 고려하여 최종 결
404minda.tistory.com
또한, <클린 아키텍처>를 읽으며 SOLID 원칙과 같은 소프트웨어 설계 기법을 접했고, 이를 활용해 모듈 설계와 구조화된 코드에 대한 고민을 확장했습니다. 특히, 프로젝트를 진행하면서 단일 책임 원칙과 의존성 역전 원칙을 어떻게 실제로 구현할 수 있을지에 대해 깊이 생각해보는 계기가 되었습니다.
타입 좁히기에 대한 개념은 이전 프로젝트에서 부족함을 크게 느꼈던 부분이었기에, 이를 보완하고자 이펙티브 타입스크립트와 우아한 타입스크립트 with 리액트를 도서관에서 빌려 읽으며 개념을 정리하고 실전 적용법을 탐구했습니다. 특히, 타입 좁히기와 타입 가드를 활용하여 조건부 로직을 안전하고 명확하게 구현하는 데 중점을 두었습니다.
이펙티브 타입스크립트 - 예스24
타입스크립트는 타입 정보를 지닌 자바스크립트의 상위 집합으로, 자바스크립트의 골치 아픈 문제점들을 해결해 준다. 이 책은 《이펙티브 C++》와 《이펙티브 자바》의 형식을 차용해 타입스
www.yes24.com
우아한 타입스크립트 with 리액트 - 예스24
주니어 프론트엔드 개발자를 위한 타입스크립트+리액트 온보딩 가이드우아한형제들은 자바스크립트와 자체 개발 웹 프레임워크인 WoowahanJS를 사용했었다. 그러나 서비스가 대규모 웹 애플리케
www.yes24.com
이 외에도 리액트를 활용한 투두리스트와 상태 관리를 다룬 포스팅을 참고하며 UI 설계 및 사용자 경험을 개선할 방법을 고민했습니다. 이 과정에서 타입 좁히기와 상태 관리에 대한 구체적인 구현 방법을 발견했으며, 이를 바탕으로 프로젝트에 적용할 방향을 구체화할 수 있었습니다.
프로젝트 진행
모듈 설계 접근 방법
이번 프로젝트는 SOLID 원칙 중 단일 책임 원칙(SRP)과 개방-폐쇄 원칙(OCP)을 중심으로 설계했습니다. 각 컴포넌트는 하나의 명확한 책임을 가지며, 컴포넌트의 확장이 용이하되 변경은 최소화하도록 설계했습니다.
- TodoApp: 애플리케이션 상태 관리와 비즈니스 로직 담당
- TodoInput: 사용자 입력 처리
- TodoList: 할 일 목록 렌더링
- TodoItem: 개별 할 일의 상태와 UI 처리
모듈 구조
해당 프로젝트는 다음과 같은 폴더 구조로 설계했습니다.
src/
components/
TodoApp.tsx # 전체 애플리케이션 로직
TodoInput.tsx # 할 일 입력 폼
TodoList.tsx # 할 일 목록
TodoItem.tsx # 개별 할 일 아이템
types/
Todo.ts
utils/
darkMode.ts
styles/
todo.css
darkmode.css
타입 좁히기 적용
이 프로젝트에서 타입 좁히기는 주로 할 일 상태(pending과 completed)를 처리하는 로직에서 활용되었습니다. 이를 이용해 상태 기반 조건부 로직이 명확하고 안전하게 구현할 수 있도록 노력했습니다.
export type TodoStatus = 'pending' | 'completed';
export interface Todo {
id: number;
text: string;
status: TodoStatus;
}
const toggleTodoStatus = (id: number) => {
setTodos((prevTodos) =>
prevTodos.map((todo) =>
todo.id === id
? {
...todo,
status: todo.status === 'pending' ? 'completed' : 'pending', // 타입 좁히기
}
: todo
)
);
};
SOLID 원칙과 모듈 설계
단일 책임 원칙과 의존성 역전 원칙을 적용해 컴포넌트 간 의존성을 최소화하고, 기능별로 코드를 분리했습니다. 예를 들어, TodoInput.tsx는 사용자 입력만 처리하며 상태 변경 로직은 TodoApp에서 관리합니다.
const TodoInput: React.FC<TodoInputProps> = ({ addTodo }) => {
const [input, setInput] = useState('');
const handleKeyPress = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter' && input.trim()) {
addTodo(input);
setInput('');
}
};
return (
<input
value={input}
onChange={(e) => setInput(e.target.value)}
onKeyDown={handleKeyPress}
placeholder="Add a task"
/>
);
};
또한, TodoApp은 구체적인 구현체가 아닌 추상화된 인터페이스에 의존합니다.
interface Storage {
save(data: string): void;
}
class LocalStorage implements Storage {
save(data: string) {
localStorage.setItem('todos', data);
}
}
이번 프로젝트는 다음과 같은 사항을 고려하며 진행되었습니다.
1. 다양한 저장 방식 추가
- 실제 배포되어 사용될 때 LocalStorage 같은 서버 연동 기능을 추가할 수 있도록 인터페이스 기반 설계
2. 추가 기능
- DayPlanner에 활용될 날짜 추가 기능 등을 고려해 쉽게 통합 가능하도록 구현
3. 리팩토링의 용이성
- SOLID 원칙을 기반으로 설계하여 코드를 변경하지 않고도 확장 가능하도록 설계
'Oops, All Code! > 📝 Study Notes' 카테고리의 다른 글
[Vue+TS] Vue 첫 만남, TypeScript로 만드는 랜덤 색상 생성기 (0) | 2024.12.02 |
---|---|
[React+TS] 달력 기반 투두 리스트로 확장, UI/UX와 상태 관리의 조화 (0) | 2024.11.11 |
React 다크모드 구현과 CSS Variables (0) | 2024.09.22 |
React 순차적 계산기: TypeScript로 마이그레이션 (0) | 2024.09.22 |
소프트웨어공학 과제로 역할 분담하기 (0) | 2024.09.19 |
- Total
- Today
- Yesterday
- 카페추천
- 어른의어휘공부
- 일급객체
- javascript
- 프로토타입
- react
- 회고
- 프론트엔드
- 소사벌
- 도서추천
- 대학생플리마켓
- 트러블슈팅
- typescript
- 도서리뷰
- 소사벌맛집
- 플리마켓후기
- 대학생팝업스토어
- 서평
- 책추천
- 우아한테크코스
- 타입좁히기
- js
- 어휘력
- 프리코스
- 경험플리마켓
- 플리마켓운영
- 안성스타필드
- 코딩테스트
- 카드뉴스
- 비즈플리마켓
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |