Master Redux: From Hand‑Written Core Logic to Modern RTK Toolkit
This article explains Redux's core concepts—Action, Reducer, Store—and demonstrates how to implement them manually before transitioning to the Redux Toolkit (RTK), highlighting the synergy between low‑level principles and efficient modern development tools for large React applications.
Redux is a classic front‑end state‑management library that solves component state sharing and traceable state changes, suitable for large React projects. This article combines hand‑written core logic with modern tools (RTK) to dissect Redux principles and show how low‑level concepts cooperate with efficient development.
1. Redux Core Three Elements: Action, Reducer, Store
Redux follows a single‑direction data flow: Action → Reducer → Store, ensuring predictability.
1. Action: the message carrier
An Action is a plain object (validated by isPlainObject) that describes what happened and carries data via payload. It must contain a type property, e.g. "INCREMENT". Example:
// Basic Action structure
const incrementAction = {
type: "INCREMENT",
payload: 1
};Action creator (pure function) simplifies Action generation:
const increment = (step) => ({
type: "INCREMENT",
payload: step
}); bindActionCreatorsautomatically dispatches actions created by an Action Creator:
function getAutodisPatchActionCreator(actionCreator, dispatch) {
return (...args) => {
const action = actionCreator(...args);
dispatch(action);
};
}
export default function bindActionCreators(actionCreators, dispatch) {
if (typeof actionCreators === 'function') {
return getAutodisPatchActionCreator(actionCreators, dispatch);
}
const result = {};
for (const key in actionCreators) {
const creator = actionCreators[key];
if (typeof creator === 'function') {
result[key] = getAutodisPatchActionCreator(creator, dispatch);
}
}
return result;
}2. Reducer: pure function for state calculation
A Reducer receives the current state and an action, returns a new state without mutating the original. It must be a pure function (no side effects, no async, no external mutation).
Initialize state using default parameters when the store dispatches the internal @@redux/INIT action:
function countReducer(state = 0, action) {
switch (action.type) {
case "INCREMENT":
return state + action.payload;
case "DECREMENT":
return state - action.payload;
default:
return state;
}
}Combine multiple reducers with combineReducers to form a root reducer:
export default function combineReducers(reducers) {
validateReducers(reducers);
return function(state = {}, action) {
const newState = {};
for (const key in reducers) {
if (reducers.hasOwnProperty(key)) {
const subReducer = reducers[key];
newState[key] = subReducer(state[key], action);
}
}
return newState;
};
}
const rootReducer = combineReducers({ user: userReducer, count: countReducer });
// Store state shape: { user: {...}, count: 0 }3. Store: unified container
The Store is created with createStore(reducer) and provides three core capabilities: storing state, dispatching actions, and notifying listeners.
Core methods
getState()returns the current state. dispatch(action) validates the action, runs the reducer, updates the state, and calls all listeners. subscribe(listener) registers a listener and returns an unsubscribe function.
Store initialization automatically dispatches an init action, allowing reducers to set default state.
2. Redux Utility Functions and Middleware
1. Utility functions
isPlainObject(obj)checks that an object’s prototype is Object.prototype. ActionTypes generates random init and unknown action types to avoid collisions.
2. Middleware: extending dispatch
Redux only supports synchronous actions; middleware wraps store.dispatch to handle async logic, logging, error handling, etc. Common middleware includes redux‑thunk (function actions) and redux‑saga (generator‑based async flows).
3. From Hand‑Written Redux to RTK: Modern Evolution
Redux Toolkit (RTK) provides utilities like createSlice (auto‑generates actions and reducers) and configureStore (simplifies store creation with built‑in middleware), dramatically reducing boilerplate.
Hand‑written core vs RTK
Hand‑written core deepens understanding of Redux’s design, enabling custom middleware and debugging.
RTK offers a concise, production‑ready API for rapid development.
RTK key tools
createSlicemerges action types, reducers, and action creators. configureStore creates a store with redux‑thunk and redux‑devtools pre‑configured.
4. Redux Workflow and Core Value
1. Complete flow (common to hand‑written and RTK)
Component calls an Action Creator (or slice.actions) to produce an Action. dispatch sends the Action to the Reducer.
Reducer computes the new state and updates the Store.
Listeners (e.g., React components) read the new state via store.getState() and re‑render.
2. Core value
By separating Action, Reducer, and Store, Redux makes state changes traceable and testable, which is essential for large applications.
5. Conclusion
Redux’s value lies in its disciplined state‑management process; hand‑written implementations reveal its simple yet rigorous logic, while RTK builds on that foundation to provide modern, efficient tooling.
Beginners should first implement the core manually to grasp fundamentals, then adopt RTK for productivity; advanced developers balance low‑level understanding with high‑level tools to maintain stable, maintainable projects.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
