학습
JavaScript 상태 관리 라이브러리 (Redux 등)
JavaScript 상태 관리 라이브러리 (Redux 등) — 중급
상태 관리 라이브러리 (Redux 등)
1. 도입 (왜 배워야 하는가)
현대의 웹 애플리케이션은 사용자 인터페이스(UI)와 애플리케이션 상태를 관리하는 데 있어 점점 복잡해지고 있습니다. 특히, 여러 컴포넌트가 상호작용하고, 데이터가 빈번하게 변경되는 경우, 상태를 일관되게 관리하는 것이 중요합니다. 만약 상태 관리를 소홀히 한다면, 데이터의 불일치, 예기치 않은 UI 업데이트, 유지보수의 어려움 등 여러 문제가 발생할 수 있습니다. 이러한 문제들은 사용자 경험을 저하시킬 수 있으며, 개발자의 생산성을 떨어트릴 수 있습니다.
상태 관리 라이브러리인 Redux는 이러한 문제를 해결하기 위해 설계되었습니다. Redux를 사용하면 애플리케이션의 상태를 중앙에서 관리할 수 있어, 데이터 흐름을 명확하게 하고 예측 가능한 상태 관리를 가능하게 합니다. 따라서 실무에서 Redux와 같은 상태 관리 라이브러리를 배우는 것은 필수적입니다.
2. 핵심 개념 설명
상태 (State)
상태는 애플리케이션의 현재 데이터를 의미합니다. 예를 들어, 사용자의 로그인 상태, 장바구니의 내용 등이 상태에 해당합니다.
- 비유: 상태는 마치 냉장고의 음식과 같습니다. 냉장고에 무엇이 있는지 항상 알아야 요리를 할 수 있습니다.
- 비유: 액션은 요리를 시작하기 위한 레시피와 같습니다. 어떤 요리를 할지(타입)와 필요한 재료(페이로드)를 명시합니다.
- 비유: 리듀서는 요리사가 요리하는 과정과 같습니다. 재료를 섞어서 새로운 요리를 만드는 거죠.
액션 (Action)
액션은 상태를 변화시키기 위해 발생하는 이벤트입니다. 액션은 타입과 페이로드를 가집니다.
리듀서 (Reducer)
리듀서는 현재 상태와 액션을 받아 새로운 상태를 반환하는 함수입니다. 상태의 변화를 담당합니다.
| 용어 | 정의 |
|---|---|
| 상태 | 애플리케이션의 현재 데이터 |
| 액션 | 상태를 변화시키는 이벤트 |
| 리듀서 | 상태 변화를 수행하는 함수 |
3. 기본 코드 예제
아래는 Redux를 사용한 기본적인 상태 관리 예제입니다.
// 액션 타입 정의
const ADD_TODO = 'ADD_TODO';
// 액션 생성 함수
const addTodo = (todo) => ({
type: ADD_TODO,
payload: todo,
});
// 초기 상태
const initialState = {
todos: []
};
// 리듀서 정의
const todoReducer = (state = initialState, action) => {
switch (action.type) {
case ADD_TODO:
return {
...state,
todos: [...state.todos, action.payload],
};
default:
return state;
}
};
// Redux 스토어 생성
const { createStore } = require('redux');
const store = createStore(todoReducer);
// 액션 디스패치
store.dispatch(addTodo('Learn Redux'));
store.dispatch(addTodo('Build a Redux app'));
// 현재 상태 출력
console.log(store.getState());
실행 결과
{ todos: [ 'Learn Redux', 'Build a Redux app' ] }
코드 동작 설명
ADD_TODO라는 액션 타입을 정의합니다.addTodo라는 액션 생성 함수를 통해 새로운 할 일을 생성합니다.initialState로 초기 상태를 정의합니다.todoReducer함수는 상태와 액션을 받아 새로운 상태를 반환합니다.createStore를 사용해 Redux 스토어를 생성합니다.dispatch메서드를 통해 액션을 스토어에 전송합니다.getState를 호출해 현재 상태를 출력합니다.- 올바른 코드:
- 올바른 코드:
- 상태 관리 라이브러리는 애플리케이션의 상태를 일관성 있게 관리하는 데 필수적입니다.
- Redux는 상태, 액션, 리듀서의 개념을 통해 이러한 관리를 가능하게 합니다.
- 실전에서는 장바구니, 로그인 상태 등 다양한 상황에서 활용됩니다.
- 액션 타입의 오타와 상태 직접 수정은 자주 발생하는 실수입니다.
- 다음 주제로는 Redux 미들웨어(예: Redux Thunk, Redux Saga)를 학습해보는 것을 추천합니다. 이를 통해 비동기 작업을 효과적으로 처리할 수 있습니다.
4. 실전 활용 예제
쇼핑몰에서 장바구니 구현
쇼핑몰 애플리케이션에서 장바구니는 사용자가 선택한 상품의 리스트를 관리하는 상태입니다. Redux를 사용하여 장바구니의 상태를 관리하면, 사용자가 상품을 추가하거나 제거할 때 상태를 쉽게 업데이트할 수 있습니다.
// 장바구니에 상품 추가 액션 생성
const ADD_TO_CART = 'ADD_TO_CART';
const addToCart = (item) => ({
type: ADD_TO_CART,
payload: item,
});
// 장바구니 리듀서
const cartReducer = (state = { cart: [] }, action) => {
switch (action.type) {
case ADD_TO_CART:
return {
...state,
cart: [...state.cart, action.payload],
};
default:
return state;
}
};
사용자 로그인 상태 관리
로그인 상태를 관리하는 것도 매우 일반적입니다. Redux를 통해 로그인 상태를 전역에서 관리하면, 어떤 컴포넌트에서든 쉽게 현재 로그인 상태를 확인하고, 업데이트할 수 있습니다.
// 로그인 액션 생성
const LOGIN = 'LOGIN';
const loginUser = (user) => ({
type: LOGIN,
payload: user,
});
// 로그인 리듀서
const authReducer = (state = { isLoggedIn: false, user: null }, action) => {
switch (action.type) {
case LOGIN:
return {
...state,
isLoggedIn: true,
user: action.payload,
};
default:
return state;
}
};
5. 흔한 실수와 주의사항
실수 1: 액션 타입 오타
const ADD_TODO = 'ADD_TODO';
store.dispatch({ type: 'AD_TODO', payload: 'Learn Redux' }); // 잘못된 액션 타입
store.dispatch(addTodo('Learn Redux')); // 올바른 액션 생성 함수 사용
실수 2: 상태 직접 수정
const todoReducer = (state, action) => {
if (action.type === ADD_TODO) {
state.todos.push(action.payload); // 상태를 직접 수정
}
return state;
};
const todoReducer = (state = initialState, action) => {
switch (action.type) {
case ADD_TODO:
return {
...state,
todos: [...state.todos, action.payload], // 상태 복사 후 수정
};
default:
return state;
}
};