完整 REDUX 内部

发布: (2025年12月2日 GMT+8 22:48)
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 Store 实现

// ------------------------------
// 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;
  };
}

示例 Reducer 与 Store 用法

// ------------------------------
// 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)会自动生成 action creator。
  • 组件 dispatch 一个 action → 可选的中间件 → 由 createSlice 生成的 slice reducer。
  • Immer 会产生不可变的 newState
  • Redux store 更新对新状态的引用。
  • React‑Redux 选择器比较前后状态切片。
  • 如果选择器的结果发生变化,已连接的组件将重新渲染。
Back to Blog

相关文章

阅读更多 »