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, andsubscribebehave 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:
- Holds state � one state tree for the whole app.
- Receives actions � through
dispatch(action). - Runs reducers � calculates the next state snapshot.
- 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:
- User clicks �Add to cart.�
- Component calls
dispatch(addItem({ id })). - Store passes action to
cartReducer. - Reducer returns next cart state.
- Store notifies React Redux subscriptions.
- 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
subscribelisteners.
?? 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.
dispatchis the only way to trigger Redux state transitions.getStateandsubscribeare foundational tools for testing and integrations.configureStoreis 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.