Skip to main content

The Redux Store: Bringing Actions and Reducers Together #111

?? Introduction

By now, you have seen actions and reducers as separate concepts. The missing piece is the object that coordinates everything: the Redux store.

Think of the store as the runtime engine for your state architecture. It holds the current state snapshot, accepts actions, runs reducers, and notifies subscribers that something changed. Without the store, actions are just plain objects and reducers are just pure functions living in isolation.

In this lesson, we will make the store concrete. You will learn what it does, how React connects to it, and why understanding the core store API (getState, dispatch, subscribe) helps even when using modern Redux Toolkit.


?? Prerequisites

Before continuing, you should understand:

  • Actions and action creators.
  • Reducers and immutable state transitions.
  • The first Redux principles from Part 1.

?? Article Outline: What You'll Master

In this lesson, you will learn:

  • What responsibilities the store owns.
  • How to create a store in modern Redux codebases.
  • How dispatch, getState, and subscribe behave in real scenarios.
  • How React components interact with store updates through hooks.

?? Section 1: What the Store Actually Does

At runtime, the Redux store does four essential jobs:

  1. Holds state � one state tree for the whole app.
  2. Receives actions � through dispatch(action).
  3. Runs reducers � calculates the next state snapshot.
  4. Notifies listeners � subscribers react to updates.

A key idea: the store does not know your business logic. It only knows how to route actions through reducers and publish state changes.

In React apps, the Provider component exposes the store to the component tree, and hooks like useSelector read from it while useDispatch sends actions into it.


?? Section 2: Creating the Store (Modern Setup)

Historically, Redux used createStore. Today, Redux Toolkit�s configureStore is the recommended approach because it includes good defaults (DevTools integration, middleware, safer checks).

// app/store.js
import { configureStore } from '@reduxjs/toolkit';
import authReducer from '../features/auth/authSlice';
import cartReducer from '../features/cart/cartSlice';

export const store = configureStore({
reducer: {
auth: authReducer,
cart: cartReducer,
},
});

Then connect it to React:

// main.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { Provider } from 'react-redux';
import { store } from './app/store';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')).render(
<Provider store={store}>
<App />
</Provider>
);

Once this is in place, every descendant component can use Redux hooks without prop drilling.


?? Section 3: Understanding Store API Through Practice

Even if hooks hide details, these APIs are still the foundation.

getState()

Returns the latest full state snapshot.

const state = store.getState();
console.log(state.cart.items.length);

Useful in tests, custom middleware, and integration points.

dispatch(action)

Sends an action into Redux. Reducers process it synchronously.

store.dispatch({ type: 'cart/itemAdded', payload: { id: 'p3' } });

In React, you usually call dispatch via useDispatch inside event handlers or effects.

subscribe(listener)

Registers a callback that runs after every dispatch.

const unsubscribe = store.subscribe(() => {
const { cart } = store.getState();
localStorage.setItem('cart', JSON.stringify(cart));
});

// later
unsubscribe();

This pattern is useful for persistence and analytics pipelines.


?? Section 4: End-to-End Flow With Hooks

Let�s walk through a common React flow:

  1. User clicks �Add to cart.�
  2. Component calls dispatch(addItem({ id })).
  3. Store passes action to cartReducer.
  4. Reducer returns next cart state.
  5. Store notifies React Redux subscriptions.
  6. Components using useSelector(state => state.cart) re-render.

This strict flow eliminates hidden side effects and keeps updates predictable.

import { useDispatch, useSelector } from 'react-redux';
import { addItem } from './cartSlice';

export function AddToCartButton({ id }) {
const dispatch = useDispatch();
const count = useSelector(state => state.cart.items.length);

return (
<button onClick={() => dispatch(addItem({ id }))}>
Add item (total: {count})
</button>
);
}

?? Common Mistakes

  • Creating multiple stores for one app (harder to reason about).
  • Dispatching non-serializable payloads without a strong reason.
  • Reading state once and assuming it never changes.
  • Forgetting to unsubscribe from manual subscribe listeners.

?? Conclusion & Key Takeaways

The Redux store is the orchestrator that turns your architecture into a working system. It centralizes state, processes actions, runs reducers, and broadcasts updates. Once you understand the store API, React Redux hooks become much more intuitive.

Key takeaways:

  • The store is the single runtime source of application state.
  • dispatch is the only way to trigger Redux state transitions.
  • getState and subscribe are foundational tools for testing and integrations.
  • configureStore is the recommended modern setup.

?? Next Steps

Continue to Connecting React and Redux with react-redux, where we will map this store architecture directly to component patterns and best practices for selectors and dispatching.


glossary

  • Store: The Redux runtime object that holds state and processes actions.
  • Dispatch: Sending an action into the store.
  • Subscriber: A listener function notified after state updates.
  • State Tree: The full nested object representing app state.
  • Provider: React Redux component that exposes the store to descendants.

Further Reading