240527 TIL

Jun Young Kim·2024년 5월 27일
0

TIL

목록 보기
28/63

Redux

Redux는 JavaScript 애플리케이션의 상태를 중앙 집중식으로 관리하기 위해 고안된 상태 관리 라이브러리입니다. 주로 React와 함께 사용되지만, 다른 JavaScript 프레임워크나 라이브러리에서도 사용할 수 있습니다. Redux는 애플리케이션의 상태를 예측 가능하게 만들고, 디버깅을 용이하게 하며, 상태 관리를 단순화합니다.

Redux의 핵심 개념

Redux는 세 가지 주요 원칙을 기반으로 합니다:

  1. 하나의 단일 진실의 원천 (Single Source of Truth)

    • 애플리케이션의 모든 상태는 하나의 스토어 안에 저장됩니다. 이 스토어는 애플리케이션의 전체 상태를 나타내며, 중앙 집중화된 상태 관리의 근간이 됩니다.
  2. 상태는 읽기 전용 (State is Read-Only)

    • 상태를 직접 변경할 수 없으며, 상태를 변경하려면 액션을 통해서만 가능합니다. 액션은 상태를 변경하는 유일한 방법입니다.
  3. 순수 함수로만 상태를 변경 (Changes are Made with Pure Functions)

    • 리듀서는 순수 함수여야 하며, 이전 상태와 액션을 받아서 새로운 상태를 반환합니다. 이는 상태의 예측 가능성을 높여줍니다.

Redux의 주요 구성 요소

Redux는 세 가지 주요 구성 요소로 이루어져 있습니다:

  1. 스토어 (Store)

    • 애플리케이션의 상태 트리를 보유합니다.
    • createStore 함수로 생성됩니다.
    • getState 메서드를 통해 현재 상태를 가져올 수 있습니다.
    • dispatch 메서드를 통해 액션을 보낼 수 있습니다.
    • subscribe 메서드를 통해 상태 변경을 감지할 수 있습니다.

2.액션 (Action)
- 상태 변경을 설명하는 객체입니다.
- 액션은 type 필드를 가지고 있으며, 상태 변경을 기술하는 추가적인 데이터를 포함할 수 있습니다.
- 액션 생성자 함수는 액션 객체를 생성하는 함수입니다.

  1. 리듀서 (Reducer)
    • 현재 상태와 액션을 받아서 새로운 상태를 반환하는 순수 함수입니다.
    • combineReducers 함수를 사용하여 여러 리듀서를 하나로 결합할 수 있습니다.

Redux의 동작 흐름

  1. 액션 생성
    • 사용자의 인터랙션이나 네트워크 요청 등으로 액션이 생성됩니다.
const addItem = (item) => ({
  type: 'ADD_ITEM',
  payload: item
});
  1. 디스패치 (Dispatch)
    • 생성된 액션이 스토어에 디스패치됩니다.
store.dispatch(addItem({ id: 1, name: 'Apple' }));
  1. 리듀서 처리
    • 디스패치된 액션은 리듀서에 의해 처리되어 새로운 상태가 생성됩니다.
const initialState = {
  items: []
};

const itemReducer = (state = initialState, action) => {
  switch (action.type) {
    case 'ADD_ITEM':
      return {
        ...state,
        items: [...state.items, action.payload]
      };
    default:
      return state;
  }
};
  1. 상태 업데이트
    • 새로운 상태가 스토어에 저장되고, 구독된 모든 리스터들이 상태 변경을 감지합니다.
store.subscribe(() => {
  console.log(store.getState());
});
  1. Redux의 React의 연동
    Redux는 React와 잘 통합될 수 있도록 react-redux 패키지를 제공합니다. 주요 구성 요소는 다음과 같습니다:

5-1. provider
- Redux 스토어를 React 컴포넌트 계층에 주입합니다.\

import { Provider } from 'react-redux';
import { createStore } from 'redux';
import rootReducer from './reducers';

const store = createStore(rootReducer);

const App = () => (
  <Provider store={store}>
    <MyComponent />
  </Provider>
);

5-2. Connect
- React 컴포넌트를 Redux 스토어에 연결합니다.
- mapStateToPropsmapDispatchToProps를 사용하여 상태와 액션을 컴포넌트의 props로 매핑합니다.

import { connect } from 'react-redux';
import { addItem } from './actions';

const MyComponent = ({ items, addItem }) => {
  return (
    <div>
      <button onClick={() => addItem({ id: 2, name: 'Banana' })}>
        Add Banana
      </button>
      <ul>
        {items.map(item => (
          <li key={item.id}>{item.name}</li>
        ))}
      </ul>
    </div>
  );
};

const mapStateToProps = state => ({
  items: state.items
});

const mapDispatchToProps = {
  addItem
};

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent);
  1. Redux DevTools
    Redux는 상태 변화를 쉽게 추적하고 디버깅할 수 있는 Redux DevTools를 제공합니다. Chrome 및 Firefox 확장 프로그램을 통해 상태의 변화를 시각화하고, 시간 여행 디버깅을 할 수 있습니다.
import { createStore } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import rootReducer from './reducers';

const store = createStore(rootReducer, composeWithDevTools());
  1. MiddleWare
    Redux 미들웨어를 사용하면 액션이 리듀서에 도달하기 전에 가로채서 추가 작업을 수행할 수 있습니다. 대표적인 미들웨어로는 redux-thunkredux-saga가 있습니다.
  • redux-thunk 사용 예시:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';

const store = createStore(rootReducer, applyMiddleware(thunk));

// Thunk 액션 생성자
const fetchItems = () => {
  return async dispatch => {
    const response = await fetch('/api/items');
    const items = await response.json();
    dispatch({ type: 'SET_ITEMS', payload: items });
  };
};

store.dispatch(fetchItems());

결론

Redux는 상태 관리의 복잡성을 줄이고 예측 가능성을 높이는 강력한 도구입니다. 액션, 리듀서, 스토어라는 세 가지 기본 개념을 통해 상태 변화를 명확하게 관리할 수 있습니다. React와의 통합, Redux DevTools, 미들웨어 등의 기능을 통해 더욱 강력하고 디버깅이 용이한 애플리케이션을 개발할 수 있습니다.

0개의 댓글