이번엔 Redux Toolkit, TypeScript, Tailwind CSS를 활용해서 전역 상태로 관리되는 플레이리스트 장바구니 화면을 구현했다.

이번 실습의 목표는 아래와 같았다.
- 음반 Mock Data 분리
- Redux Store 생성
- cartSlice 설계
- 수량 증가, 감소, 삭제, 전체 삭제 기능 구현
- 총 수량과 총 금액 자동 계산
- React 컴포넌트와 Redux 상태 연결
- Tailwind CSS로 UI 구성
1. 음반 Mock Data 분리
먼저 음반 정보를 constants/cartItems.ts 파일로 분리한다.
각 음반 데이터는 id, title, singer, price, img, amount 값을 가진다.
export interface CartItem {
id: string
title: string
singer: string
price: string
img: string
amount: number
}
이렇게 타입을 먼저 정의해두니 이후 Redux Slice나 컴포넌트에서 데이터를 사용할 때 훨씬 안정적으로 다룰 수 있었다.
2. Redux Store 구성
export const store = configureStore({
reducer: {
cart: cartReducer,
},
})
Redux Toolkit의 configureStore를 사용해서 전역 Store를 만들었다.
<Provider store={store}>
<App />
</Provider>
그리고 main.tsx에서 앱 전체를 Provider로 감싸 Redux Store를 연결했다.
이 설정을 통해 앱 내부 어디서든 Redux 상태에 접근할 수 있게 되었다.
3. cartSlice 설계
장바구니 상태는 다음 세 가지 값을 중심으로 구성했다.
interface CartState {
cartItems: CartItem[]
amount: number
total: number
}
- cartItems: 장바구니 음반 목록
- amount: 전체 수량
- total: 전체 금액
그리고 Redux Toolkit의 createSlice를 사용해서 장바구니 관련 액션들을 정의했다.
- increase: 특정 음반 수량 증가
- decrease: 특정 음반 수량 감소
- removeItem: 특정 음반 삭제
- clearCart: 장바구니 전체 삭제
- calculateTotals: 전체 수량과 금액 계산
특히 decrease에서는 수량이 1보다 작아지면 해당 음반이 자동으로 장바구니에서 제거되도록 처리했다.
if (item.amount < 1) {
state.cartItems = state.cartItems.filter(
(cartItem) => cartItem.id !== action.payload,
)
}
장바구니의 전체 수량과 총 금액은 calculateTotals에서 계산했다.
Mock Data의 price 값이 문자열이었기 때문에 계산 시 Number(item.price)로 변환해주었다.
totals.amount += item.amount
totals.total += item.amount * Number(item.price)
그리고 컴포넌트에서는 useEffect를 사용해서 장바구니 목록이 변경될 때마다 자동으로 합계를 다시 계산하게 만들었다.
useEffect(() => {
dispatch(calculateTotals())
}, [cartItems, dispatch])
5. 컴포넌트와 Redux 연결
컴포넌트에서는 useSelector로 Redux 상태를 가져오고, useDispatch로 액션을 실행했다.
const dispatch = useAppDispatch()
const { cartItems, amount, total } = useAppSelector((state) => state.cart)
수량 증가 버튼을 누르면 increase 액션이 실행된다.
onClick={() => dispatch(increase(item.id))}
수량 감소 버튼은 decrease, 제거 버튼은 removeItem, 전체 삭제 버튼은 clearCart를 실행하도록 연결했다.
6. UI
UI는 Tailwind CSS를 사용해서 구성했다.
최종적으로는 다음과 같은 구조로 구현했다.
- 상단 Navbar
- 장바구니 아이콘과 전체 수량 표시
- 음반 리스트
- 음반 이미지, 제목, 가수명, 가격 표시
- 수량 증가/감소 버튼
- 개별 제거 버튼
- 총 금액 표시
- 전체 삭제 버튼
7. 배운 점
Redux Toolkit의 전체 흐름을 한 번에 경험할 수 있었다.
처음에는 Redux가 복잡하게 느껴질 수 있지만 Redux Toolkit을 사용하니 Slice 안에서 상태와 액션을 함께 관리할 수 있어서 구조가 훨씬 명확했다. 또한 장바구니처럼 여러 값이 서로 연결되어 있는 기능에서는 전역 상태 관리가 왜 필요한지 이해할 수 있었다.수량이 바뀌면 개별 음반의 amount뿐만 아니라 전체 수량과 총 금액도 함께 바뀌어야 한다. 이런 상태들을 한 곳에서 관리하니 UI와 데이터 흐름이 더 깔끔해졌다.
'Web' 카테고리의 다른 글
| Redux Toolkit에서 Zustand로 리팩토링하기 (0) | 2026.05.31 |
|---|---|
| Modal Slice 활용하여, 모달 기능 추가 (0) | 2026.05.30 |
| TanStack Query 실습 (0) | 2026.05.09 |
| OAuth 로그인 구현 (Google) (0) | 2026.05.01 |
| Refresh 토큰을 활용한 끊김 없는 로그인 유지하기 (0) | 2026.04.30 |