전체 Redux 내부

발행: (2025년 12월 2일 오후 11:48 GMT+9)
3 min read
원문: Dev.to

Source: Dev.to

Redux 내부 흐름 다이어그램

┌─────────────────────────────┐
│        Your Component        │
│   dispatch(action)           │
└──────────────┬──────────────┘


┌─────────────────────────────┐
│        Store.dispatch        │
└──────────────┬──────────────┘


┌─────────────────────────────┐
│      Middleware Chain        │
│ (logger → thunk → custom..) │
└──────────────┬──────────────┘


┌─────────────────────────────┐
│           Reducer            │
│  newState = reducer(old, a)  │
└──────────────┬──────────────┘


┌─────────────────────────────┐
│      Store Updates State     │
│    state = newState (new ref)│
└──────────────┬──────────────┘


┌─────────────────────────────┐
│ React-Redux Subscriptions   │
│  useSelector listeners       │
│  compare prev vs next        │
└──────────────┬──────────────┘


┌─────────────────────────────┐
│     React Re-renders UI      │
└─────────────────────────────┘

간소화된 Redux 스토어 구현

// ------------------------------
// Mini Redux Implementation
// ------------------------------

function createStore(reducer) {
  let state = reducer(undefined, { type: "@@INIT" });
  let listeners = [];

  return {
    getState() {
      return state;
    },

    dispatch(action) {
      state = reducer(state, action);
      listeners.forEach((l) => l());
      return action;
    },

    subscribe(listener) {
      listeners.push(listener);
      return () => {
        listeners = listeners.filter((l) => l !== listener);
      };
    },
  };
}

function combineReducers(reducers) {
  return function rootReducer(state = {}, action) {
    const nextState = {};

    for (let key in reducers) {
      nextState[key] = reducers[key](state[key], action);
    }

    return nextState;
  };
}

예제 리듀서 및 스토어 사용법

// ------------------------------
// Example Reducers
// ------------------------------

function counterReducer(state = { value: 0 }, action) {
  switch (action.type) {
    case "INCREMENT":
      return { value: state.value + 1 };
    case "DECREMENT":
      return { value: state.value - 1 };
    default:
      return state;
  }
}

function userReducer(state = { name: "" }, action) {
  switch (action.type) {
    case "SET_NAME":
      return { name: action.payload };
    default:
      return state;
  }
}

// ------------------------------
// Combine reducers & create store
// ------------------------------

const rootReducer = combineReducers({
  counter: counterReducer,
  user: userReducer,
});

const store = createStore(rootReducer);

// ------------------------------
// Demo Usage
// ------------------------------

store.subscribe(() => {
  console.log("State updated:", store.getState());
});

store.dispatch({ type: "INCREMENT" });
store.dispatch({ type: "INCREMENT" });
store.dispatch({ type: "DECREMENT" });
store.dispatch({ type: "SET_NAME", payload: "Zeeshan" });

핵심 포인트

  • createSlice (Redux Toolkit에서 제공) 은 액션 생성자를 자동으로 생성합니다.
  • 컴포넌트가 액션을 디스패치 → 선택적 미들웨어 → createSlice 로 생성된 슬라이스 리듀서.
  • Immer 가 불변 newState 를 생성합니다.
  • Redux 스토어가 새로운 상태에 대한 참조를 업데이트합니다.
  • React‑Redux 셀렉터가 이전과 다음 상태 슬라이스를 비교합니다.
  • 셀렉터 결과가 변경되면 연결된 컴포넌트가 다시 렌더링됩니다.
Back to Blog

관련 글

더 보기 »