icon안동민 개발노트

Redux 기초 개념 소개


 Redux는 JavaScript 애플리케이션을 위한 예측 가능한 상태 컨테이너입니다.

 주로 React와 함께 사용되지만, 다른 프레임워크나 라이브러리와도 사용할 수 있습니다.

 Redux는 복잡한 상태 관리를 단순화하고 애플리케이션의 동작을 예측 가능하게 만드는 것을 목표로 합니다.

Redux의 핵심 개념

 Redux는 세 가지 주요 개념을 중심으로 구성됩니다.

  1. Store : 애플리케이션의 전체 상태를 보관하는 객체입니다.
  2. Action : 상태 변경을 설명하는 객체입니다.
  3. Reducer : 현재 상태와 액션을 받아 새로운 상태를 반환하는 순수 함수입니다.

Redux의 동작 원리

  1. 사용자의 상호작용이나 데이터 로딩 등의 이벤트가 발생하면 Action이 생성됩니다.
  2. 생성된 Action은 Store에 전달됩니다.
  3. Store는 현재 상태와 Action을 Reducer에 전달합니다.
  4. Reducer는 새로운 상태를 계산하여 반환합니다.
  5. Store는 새로운 상태를 저장하고, 구독 중인 컴포넌트에게 상태 변경을 알립니다.

Redux의 세 가지 원칙

  1. Single source of truth : 애플리케이션의 전체 상태는 하나의 스토어 안에 객체 트리 구조로 저장됩니다.
  2. State is read-only : 상태를 변경하는 유일한 방법은 액션을 전달하는 것입니다.
  3. Changes are made with pure functions : 상태 변경을 수행하는 리듀서는 순수 함수여야 합니다.

간단한 Redux 예제

// Action 생성자
const increment = () => ({ type: 'INCREMENT' });
const decrement = () => ({ type: 'DECREMENT' });
 
// Reducer
const counterReducer = (state = 0, action) => {
  switch (action.type) {
    case 'INCREMENT':
      return state + 1;
    case 'DECREMENT':
      return state - 1;
    default:
      return state;
  }
};
 
// Store 생성
import { createStore } from 'redux';
const store = createStore(counterReducer);
 
// 상태 변경 구독
store.subscribe(() => console.log(store.getState()));
 
// 액션 디스패치
store.dispatch(increment()); // 출력: 1
store.dispatch(increment()); // 출력: 2
store.dispatch(decrement()); // 출력: 1

React 애플리케이션에 Redux 통합하기

 Redux를 React 애플리케이션에 통합하기 위해서는 주로 react-redux 라이브러리를 사용합니다.

 기본적인 통합 과정은 다음과 같습니다.

  1. Redux 스토어 생성
  2. Provider 컴포넌트로 React 앱 래핑
  3. useSelectoruseDispatch 훅을 사용하여 컴포넌트에서 상태 접근 및 액션 디스패치
import { Provider } from 'react-redux';
import { createStore } from 'redux';
import rootReducer from './reducers';
 
const store = createStore(rootReducer);
 
ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

 컴포넌트에서 Redux 사용

import { useSelector, useDispatch } from 'react-redux';
 
function Counter() {
  const count = useSelector(state => state.count);
  const dispatch = useDispatch();
 
  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => dispatch({ type: 'INCREMENT' })}>+</button>
      <button onClick={() => dispatch({ type: 'DECREMENT' })}>-</button>
    </div>
  );
}

Redux의 장단점

 장점

  1. 예측 가능한 상태 관리 : 단방향 데이터 흐름으로 상태 변화를 추적하기 쉽습니다.
  2. 중앙화된 상태 : 애플리케이션의 모든 상태가 한 곳에서 관리됩니다.
  3. 디버깅 용이성 : Redux DevTools를 사용하여 상태 변화를 쉽게 추적할 수 있습니다.
  4. 미들웨어 지원 : 비동기 작업이나 로깅 등을 위한 미들웨어를 사용할 수 있습니다.

 단점

  1. 보일러플레이트 코드 : 작은 기능을 구현하는 데도 많은 코드가 필요할 수 있습니다.
  2. 학습 곡선 : Redux의 개념과 패턴을 익히는 데 시간이 걸릴 수 있습니다.
  3. 과도한 사용 : 모든 상태를 Redux로 관리하면 불필요한 복잡성이 증가할 수 있습니다.

Redux 사용의 이유

 Redux는 다음과 같은 상황에서 특히 유용합니다.

  1. 복잡한 상태 로직 관리 : 여러 컴포넌트에서 공유되는 복잡한 상태를 관리할 때
  2. 대규모 애플리케이션 : 많은 컴포넌트와 복잡한 데이터 흐름을 가진 애플리케이션에서
  3. 상태 변화 추적 : 상태 변화를 추적하고 디버깅해야 하는 경우
  4. 서버 상태 관리 : 서버에서 가져온 데이터를 일관성 있게 관리해야 할 때

 Redux는 강력한 상태 관리 도구이지만, 모든 React 애플리케이션에 필수적인 것은 아닙니다.

 작은 규모의 애플리케이션이나 단순한 상태 관리만 필요한 경우에는 React의 내장 상태 관리 기능(useState, useReducer, Context API)만으로도 충분할 수 있습니다.

 Redux를 도입할 때는 애플리케이션의 복잡성, 팀의 경험, 유지보수 용이성 등을 고려해야 합니다.

 Redux는 강력한 도구이지만, 그만큼 복잡성도 증가하므로 적절한 상황에서 사용하는 것이 중요합니다.

 최근에는 Redux Toolkit이라는 공식 도구가 나와 Redux 사용의 복잡성을 줄이고 있습니다. 이는 보일러플레이트 코드를 줄이고, 일반적인 Redux 사용 패턴을 단순화하는 데 도움을 줍니다.

 결론적으로, Redux는 복잡한 상태 관리 문제를 해결하는 강력한 도구입니다. 그러나 모든 문제에 대한 해답은 아니며, 프로젝트의 요구사항과 특성을 고려하여 적절히 사용해야 합니다.