L1: Setup Redux Store
Install Redux Toolkit and configure the Redux store
Welcome to Module 6! In this module, we'll introduce Redux Toolkit - a powerful state management library that allows you to share state across your entire application.
Why Redux?
So far, we've managed state locally within components using useState. This works great for simple apps, but as your application grows, you'll face challenges:
Problems with Local State:
Redux Solutions:
- Single source of truth - One global store for all shared state
- Predictable updates - State changes through pure functions
- Easy debugging - Track every state change with DevTools
- No prop drilling - Access state from any component
Redux Architecture
Redux uses a unidirectional data flow:
┌─────────────────────────────────────────────┐
│ │
│ Component dispatches Action │
│ │ │
│ ↓ │
│ Store receives Action │
│ │ │
│ ↓ │
│ Reducer updates State │
│ │ │
│ ↓ │
│ Component re-renders with new State │
│ │ │
│ └─────────────────────────────────────┘Key Concepts:
Store
The store holds your entire application state in one JavaScript object:
{
listings: {
items: [],
favorites: [],
status: 'idle'
},
user: {
profile: null,
isAuthenticated: false
}
}Think of it as a centralized database for your app's state.
Actions
Actions are plain objects describing what happened:
{ type: 'listings/toggleFavorite', payload: 123 }
{ type: 'user/signIn', payload: { email, password } }They tell Redux "something happened" without specifying how to update state.
Reducers
Reducers are pure functions that specify how state changes:
function listingsReducer(state, action) {
switch (action.type) {
case 'listings/toggleFavorite':
// Return new state
return { ...state, favorites: [...state.favorites, action.payload] };
default:
return state;
}
}Given current state + action → return new state.
Redux Toolkit
Redux Toolkit is the official, recommended way to write Redux code. It simplifies Redux significantly:
Traditional Redux:
// ~50 lines of boilerplate per feature
const ADD_TODO = 'ADD_TODO';
const addTodo = (text) => ({ type: ADD_TODO, payload: text });
function todosReducer(state = [], action) {
switch (action.type) {
case ADD_TODO:
return [...state, { id: Date.now(), text: action.payload }];
default:
return state;
}
}Redux Toolkit:
// ~10 lines, same functionality
const todosSlice = createSlice({
name: 'todos',
initialState: [],
reducers: {
addTodo: (state, action) => {
state.push({ id: Date.now(), text: action.payload });
}
}
});Redux Toolkit includes:
- ✅
configureStore()- Simplified store setup - ✅
createSlice()- Combines actions + reducers - ✅
createAsyncThunk()- Handle async logic - ✅ Immer built-in - Write "mutating" code safely
- ✅ Redux DevTools - Pre-configured
What We're Building
In this lesson, we'll:
- Install Redux Toolkit - Add the library to our project
- Create the store - Set up the Redux store
- Configure the store - Add basic configuration
By the end, you'll have a working Redux store ready to hold application state!
Step 1: Install Redux Toolkit
Redux Toolkit comes as two packages:
@reduxjs/toolkit- Redux Toolkit corereact-redux- React bindings for Redux
Install both packages:
npm install @reduxjs/toolkit react-reduxWhat's the difference?
@reduxjs/toolkitprovides Redux logic (store, slices, thunks)react-reduxconnects Redux to React (hooks likeuseSelector,useDispatch)
Step 2: Create Store File
Create a new directory and file for our Redux store:
mkdir -p src/state
touch src/state/store.jsThis file will configure and export our Redux store.
Step 3: Configure Store
Open src/state/store.js and add:
import { configureStore } from '@reduxjs/toolkit';
export const store = configureStore({
reducer: {
// Reducers will be added here
},
});What's happening here?
Understanding the Redux Store
The store is an object with three main methods:
getState() - Returns the current state:
import { store } from './state/store';
const currentState = store.getState();
console.log(currentState);
// {
// listings: { items: [], favorites: [] },
// user: { profile: null }
// }In React components, use useSelector() instead of calling getState() directly.
dispatch(action) - Dispatches an action to update state:
import { store } from './state/store';
store.dispatch({
type: 'listings/toggleFavorite',
payload: 123
});In React components, use useDispatch() hook instead.
subscribe(listener) - Listen for state changes:
import { store } from './state/store';
const unsubscribe = store.subscribe(() => {
console.log('State changed:', store.getState());
});
// Later: stop listening
unsubscribe();React Redux handles subscriptions automatically via useSelector().
Verify Setup
Let's verify the store is configured correctly. Add a temporary log:
import { configureStore } from '@reduxjs/toolkit';
export const store = configureStore({
reducer: {
// Reducers will be added here
},
});
// Temporary: verify store works
console.log('Redux store configured:', store.getState());You should see an empty object logged when the app loads:
Redux store configured: {}Note: Remove this console.log after verifying - we'll access state properly through React hooks!
What's Next?
Great! You've set up the Redux store. In the next lesson, we'll:
- Connect Redux to React - Add the
Providercomponent - Make store available - Wrap our app with Redux
- Verify connection - Ensure components can access the store
✅ Lesson Complete! You've installed Redux Toolkit and configured the store. The foundation for global state management is ready!
Key Takeaways
- ✅ Redux provides a single source of truth for application state
- ✅ Redux Toolkit simplifies Redux with less boilerplate
- ✅
configureStore()creates a store with good defaults - ✅ The store has three methods:
getState(),dispatch(),subscribe() - ✅ Empty reducer object is valid - we'll add slices next!