Redux “under the hood”

To understand Redux “under the hood,” let’s break down its core principles and how they work together:

1. The Store:

  • Single Source of Truth:
    • The Redux store is a single JavaScript object that holds the entire application’s state.
    • This centralized store makes it easy to manage and access state from any part of the application.
  • createStore(reducer, [preloadedState], [enhancer]):
    • This function creates the Redux store.
    • It takes a reducer function as its primary argument.
    • Optionally, it can take an initial state (preloadedState) and store enhancers.
  • Store Methods:
    • getState(): Returns the current state of the application.
    • dispatch(action): Dispatches an action to update the state.
    • subscribe(listener): Registers a listener function that will be called1 whenever the state changes.
    • replaceReducer(nextReducer): Replaces the current reducer with a new reducer.

2. Actions:

  • Plain JavaScript Objects:
    • Actions are plain JavaScript objects that describe what happened in the application.
    • They must have a type property that indicates the type of action.2
  • Action Creators:
    • Action creators are functions that create and return action objects.
    • They simplify the process of creating actions.
  • dispatch(action):
    • The dispatch function sends an action to the Redux store.

3. Reducers:

  • Pure Functions:
    • Reducers are pure functions that take the current state and an action as arguments and return a new state.
    • They3 must be pure, meaning they should not have side effects and should always return the same output for the same input.
  • State Immutability:
    • Reducers must treat the state as immutable. Instead of modifying the existing state, they should create a new state object.
  • (state, action) => newState:
    • The reducer function’s signature.
  • combineReducers(reducers):
    • This function combines multiple reducers into a single root reducer.

4. The Data Flow:

  1. Action Dispatch:
    • A component or other part of the application dispatches an action using store.dispatch(action).
  2. Reducer Execution:
    • The Redux store calls the reducer function, passing in the current state and the dispatched action.
  3. State Update:
    • The reducer creates a new state object based on the action and returns it.
  4. Store Update:
    • The Redux store updates its internal state with the new state returned by the reducer.
  5. Listener Notification:
    • The Redux store notifies all registered listeners (components that are subscribed to the store) that the state has changed.
  6. Component Re-rendering:
    • Components that are subscribed to the store re-render to reflect the new state.

Key Concepts:

  • Immutability: Redux relies heavily on immutability to ensure predictable state updates.
  • Pure Functions: Reducers are pure functions, which makes them easy to test and reason about.
  • Single Store: The single store simplifies state management and makes it easier to debug.
  • Middleware: Middleware enhances Redux’s functionality by intercepting actions before they reach the reducer. This is used for things like asynchronous actions (e.g., Redux Thunk, Redux Saga).

In essence:

Redux provides a predictable and manageable way to handle application state by enforcing a strict data flow and relying on pure functions and immutability.