Redux Terminology
Every Redux word you will meet in this course - store, action, reducer, dispatch, selector, middleware and more - defined once in simple English, shown working in one runnable script, with the pairs people mix up.
What you will be able to do
- Define the core Redux terms in your own words
- See each term in a running example and recognise it in real code
- Tell apart the pairs people mix up: action and action creator, reducer and slice, selector and useSelector
- Follow Redux naming conventions for actions, slices and selectors
- Use this lesson as a reference for the rest of the course
The idea, in plain English
Lesson 9 showed the shape of Redux: the loop. This lesson gives every part of it a precise name. It ends Module 1, and it is written to be used later: when a word in Module 5 or Module 9 is not clear, come back here.
The terms are grouped by job: the data itself, describing changes, making changes, reading the state, and the helpers around the loop. Each definition is short and simple, with a line of code and a pointer to the module that teaches it properly.
All the terms are also shown working in one script, glossary.mjs, run with Redux Toolkit 2.13.0 in Node 22 - so every definition here matches what the code really does.
Worked example: A glossary you can come back to for the rest of the course - and one script that shows every term working.
Lesson 9’s loop, labelled with the terms from this lesson. After the last box, the next user action starts the loop again at the top.
How to use this glossary
Read it once now, quickly - do not try to memorise it. The rest of the course uses these words exactly as defined here. When a later lesson uses a word you are not sure about, search this page for it.
Each table row gives the term, a simple definition, and a small code example. The full script at the end shows all of them working together.
1. The data
These words describe what Redux holds and how it is organised.
StateThe app’s shared data at one moment: a plain JavaScript object. Module 2.Initial stateThe value of a part of the state before any action has happened.StoreThe one object that holds the state, runs the reducers and notifies subscribers. Module 2.getStateRead the whole current state from the store.Root reducer / state shapeThe reducer for the whole state, built from one reducer per key. Its keys are the shape of the state. Module 12.SliceRedux Toolkit: one key of the state plus its reducers and action creators, made with createSlice. Module 4.2. Describing changes
In Redux you do not change the state - you describe what happened. These words are about that description.
A good habit, recommended by the Redux style guide: name actions as events that already happened ("cart/added", "user/loggedOut"), not as commands ("setCart"). The part before the slash is the slice name; createSlice adds it for you.
ActionA plain object that describes what happened. It must have a type. Module 6.TypeA string naming the event, usually "sliceName/eventName".PayloadThe extra data an action carries. By convention it is called payload.Action creatorA function that makes an action. createSlice makes one per reducer.3. Making changes
These words describe how an action becomes a new state.
One point confuses everybody at first. Inside createSlice, reducers seem to change the state directly: state.items.push(...). Redux Toolkit uses a library called Immer, which records those changes on a draft copy and produces a brand-new state. In glossary.mjs we called the reducer with { items: ["Python"] }: it returned { items: ["Python", "Redux"] }, and the original object still had one item. Module 4 explains how.
DispatchSend an action to the store. The only way to change state.ReducerA function (state, action) -> new state. Modules 2-4.Pure functionSame input -> same output, and no side effects: no server calls, no random values, no changing the input. Reducers must be pure.Immutable updateMake a new object instead of changing the old one (Lesson 4).ImmerThe library inside Redux Toolkit that lets reducers write "mutating" code safely.Frozen stateRedux Toolkit freezes the state so accidental changes fail (Lesson 1).4. Reading the state
These words are about getting data out of the store and into components.
SelectorA function that takes the whole state and returns one piece of it. Module 7.SubscribeAsk the store to call a function after every dispatch. Returns a function to stop.Providerreact-redux: makes the store available to all components below it. Module 5.useSelectorreact-redux hook: run a selector, and re-render when its result changes. Module 5.useDispatchreact-redux hook: get the store’s dispatch function in a component. Module 5.5. Around the loop
These are the helpers that sit around the basic loop: for logging, async work, server data and debugging.
MiddlewareA function that sees every action before the reducers. Can log, delay, stop or add actions. Module 9.ThunkA function you dispatch instead of an action, used for async work. Module 8.createAsyncThunkRedux Toolkit: makes a thunk that dispatches pending, then fulfilled or rejected.pending / fulfilled / rejectedThe three actions of an async thunk: started, succeeded, failed.RTK QueryRedux Toolkit’s cache for server state (Lesson 3). Module 10.Redux DevToolsA browser extension that shows every action and the state after it; configureStore connects to it in development.Redux Toolkit (RTK)The official, modern way to write Redux: configureStore, createSlice and more. Module 4.EnhancerAn advanced way to extend the store itself. Rarely written by hand. Module 4.Every term, in one script
This script uses almost every word from the tables above. Read the comments in capital letters - each one names a term - and compare them with the output.
Look at the last two lines of the output. The subscriber was notified 3 times: once for cart/added, and once each for the thunk’s pending and fulfilled actions. After unsubscribe, another dispatch did not notify it, so the count stayed at 3.
import { configureStore, createAsyncThunk, createSlice } from "@reduxjs/toolkit";
// SLICE: one part of the state + its reducers + its action creators
const cartSlice = createSlice({
name: "cart",
initialState: { items: [] }, // INITIAL STATE
reducers: {
added(state, action) { // a REDUCER (case)
state.items.push(action.payload);
},
},
});
// ACTION CREATOR: a function that makes an action
const { added } = cartSlice.actions;
console.log("action creator: ", typeof added, "| added.type =", added.type);
// ACTION: a plain object { type, payload }
const action = added("Redux");
console.log("action: ", action);
// REDUCER: (state, action) -> new state. Pure: same input, same output, no changes to the input
const before = { items: ["Python"] };
const after = cartSlice.reducer(before, action);
console.log("reducer: ", JSON.stringify(before), "->", JSON.stringify(after), "| input unchanged:", before.items.length === 1);
// MIDDLEWARE: sees every action before the reducers
const seen = [];
const logger = () => (next) => (a) => { seen.push(a.type); return next(a); };
// THUNK: an async function you can dispatch
const loadCart = createAsyncThunk("cart/load", async () => ["Python", "Redux"]);
// STORE: holds the state; ROOT REDUCER built from the slices
const store = configureStore({
reducer: { cart: cartSlice.reducer },
middleware: (getDefault) => getDefault().concat(logger),
});
console.log("store state: ", JSON.stringify(store.getState()));
// SUBSCRIBE: be told after every dispatch
let notified = 0;
const unsubscribe = store.subscribe(() => notified++);
// DISPATCH: the only way to send an action
store.dispatch(added("Docker"));
console.log("after dispatch: ", JSON.stringify(store.getState()), "| subscribers notified:", notified);
// SELECTOR: a function that reads a piece of state
const selectItemCount = (state) => state.cart.items.length;
console.log("selector: ", selectItemCount(store.getState()));
// dispatching a thunk returns a promise
const result = await store.dispatch(loadCart());
console.log("thunk dispatched: ", result.type, "| middleware saw:", seen.join(", "));
// IMMUTABLE: the state is frozen - you cannot edit it directly
console.log("state is frozen: ", Object.isFrozen(store.getState().cart));
unsubscribe();
store.dispatch(added("Pandas"));
console.log("after unsubscribe, notified still:", notified);action creator: function | added.type = cart/added
action: { type: 'cart/added', payload: 'Redux' }
reducer: {"items":["Python"]} -> {"items":["Python","Redux"]} | input unchanged: true
store state: {"cart":{"items":[]}}
after dispatch: {"cart":{"items":["Docker"]}} | subscribers notified: 1
selector: 1
thunk dispatched: cart/load/fulfilled | middleware saw: cart/added, cart/load/pending, cart/load/fulfilled
state is frozen: true
after unsubscribe, notified still: 3const loadCart = createAsyncThunk("cart/load", async () => {
throw new Error("server down");
});
const result = await store.dispatch(loadCart());
console.log(result.type, "|", result.error.message);
// cart/load/rejected | server downPairs people mix up
Most confusion in Redux comes from a few pairs of words that sound alike. Here they are side by side.
Action vs action creatorAn action is an object: { type, payload }. An action creator is a function that returns one: added("Redux").Action vs dispatchThe action is the message. dispatch is sending it. Creating an action does nothing until it is dispatched.Reducer vs sliceA reducer is a function. A slice is a bundle made by createSlice: a reducer plus action creators plus a name.Store vs stateThe store is the container with methods (dispatch, getState, subscribe). The state is the plain data inside it.Selector vs useSelectorA selector is a plain function of the state. useSelector is the React hook that runs it and re-renders on change.Middleware vs reducerMiddleware sees actions and may do side effects, but does not calculate state. Reducers calculate state and must have no side effects.Thunk vs actionAn action is a plain object that reaches reducers. A thunk is a function; it never reaches reducers - it dispatches actions itself.Naming conventions
Good names make Redux code read like a story of what happened. These are the conventions used in this course, following the Redux style guide.
SlicesA noun for the feature.Action types"slice/event", in the past tense - what happened, not what to do.Action creatorsThe same event name, from createSlice.SelectorsStart with select.ThunksA verb for the work they start.Common questions
Is "state" in Redux the same as "state" in useState? The idea is the same - data that changes and the screen depends on (Lesson 1). Redux state is shared by the whole app; useState belongs to one component.
Why do actions need a type string? Because every reducer is called for every action (Lesson 9), and the type is how each one decides whether the action concerns it. It also makes the action log readable.
Do I need to learn all of these now? No. Learn store, action, dispatch, reducer and selector now - they are the loop. The rest arrive with their own modules.
Is Redux Toolkit a different library from Redux? No. Redux Toolkit is the official package for writing Redux. It uses the Redux core inside; it removes repeated code and adds safe defaults.
The six words to know now
StoreHolds the state.
configureStore({ reducer })ActionDescribes what happened.
{ type: "cart/added", payload }DispatchSends an action to the store.
store.dispatch(action)
ReducerCalculates the new state.
(state, action) => newState
SelectorReads one piece of state.
(state) => state.cart.items
MiddlewareSees every action first.
(store) => (next) => (action) => next(action)
Try it yourself
The code does not change. Swap the content string and the program does something else entirely.
“Run glossary.mjs. Change added("Docker") to two dispatches. How many times is the subscriber notified now?”
“Call cartSlice.reducer(before, action) twice with the same arguments. Are the results equal? Is before changed?”
“Make loadCart throw an error. Which action type does the middleware see last?”
“Rename an action in your own code from a command ("setUser") to an event ("user/loggedIn"). Does the action log read better?”
What usually goes wrong
An action creator only makes an object. Nothing changes until you dispatch it.
✗ added("Docker");✓ dispatch(added("Docker"));Name what happened, not what to do. Events read well in logs and let several slices react.
✗ "cart/setItems"✓ "cart/itemAdded"Reducers must be pure. Server calls, random values and timers go in thunks or middleware.
✗ added(state) { fetch("/api/cart"); }✓ const loadCart = createAsyncThunk("cart/load", fetchCart);Write selectors as plain functions (easy to test and reuse), then pass them to useSelector.
✗ useSelector((state) => state.cart.items.filter(...)) // logic hidden in a component✓ const selectVisibleItems = (state) => ...;
useSelector(selectVisibleItems);Practice
Write these yourself before opening anything. Getting them wrong first is most of how this sticks.
Match each term to its job: (1) reducer, (2) selector, (3) dispatch, (4) action, (5) middleware, (6) store. Jobs: (a) holds the state, (b) describes what happened, (c) sends an action, (d) calculates the new state, (e) reads a piece of state, (f) sees every action first.
Show hintHide hint
Follow the loop in the diagram.
Show solutionHide solution
(1) reducer -> (d) calculates the new state
(2) selector -> (e) reads a piece of state
(3) dispatch -> (c) sends an action
(4) action -> (b) describes what happened
(5) middleware -> (f) sees every action first
(6) store -> (a) holds the stateIn this line, name each part: dispatch(cartSlice.actions.added("Redux"))
Show hintHide hint
There are four things: a function that sends, a slice, an action creator, and a payload.
Show solutionHide solution
dispatch - sends the action to the store
cartSlice - the slice
.actions.added - an action creator made by the slice
"Redux" - the payload
added("Redux") - returns the action { type: "cart/added", payload: "Redux" }Rename these actions as events: "setLoggedIn", "updateCartItems", "toggleSidebarOpen".
Show hintHide hint
slice/event, past tense - what happened?
Show solutionHide solution
"setLoggedIn" -> "auth/loggedIn"
"updateCartItems" -> "cart/itemAdded" (or itemRemoved - say which)
"toggleSidebarOpen" -> "ui/sidebarToggled" (and ask Lesson 2: should it be local?)Label a store file
Copy this small store file and write the Redux term next to every line that has one. Then answer: which line would you change to log every action?
- Label: slice, initial state, reducer, action creator, store, root reducer, selector, dispatch, subscribe
- Say where a logger middleware would be added
import { configureStore, createSlice } from "@reduxjs/toolkit";
const savedSlice = createSlice({
name: "saved",
initialState: { ids: [] },
reducers: {
lessonSaved(state, action) {
state.ids.push(action.payload);
},
},
});
const { lessonSaved } = savedSlice.actions;
const selectSavedCount = (state) => state.saved.ids.length;
const store = configureStore({ reducer: { saved: savedSlice.reducer } });
store.subscribe(() => console.log(selectSavedCount(store.getState())));
store.dispatch(lessonSaved("redux-10"));Show one solutionHide solution
import { configureStore, createSlice } from "@reduxjs/toolkit";
const savedSlice = createSlice({ // SLICE
name: "saved", // its name: action types start with "saved/"
initialState: { ids: [] }, // INITIAL STATE
reducers: {
lessonSaved(state, action) { // REDUCER case (Immer draft)
state.ids.push(action.payload); // action.payload = the PAYLOAD
},
},
});
const { lessonSaved } = savedSlice.actions; // ACTION CREATOR
const selectSavedCount = (state) => state.saved.ids.length; // SELECTOR
const store = configureStore({ // STORE
reducer: { saved: savedSlice.reducer }, // ROOT REDUCER: the state shape { saved }
// middleware: (getDefault) => getDefault().concat(logger), <- add MIDDLEWARE here
});
store.subscribe(() => console.log(selectSavedCount(store.getState()))); // SUBSCRIBE
store.dispatch(lessonSaved("redux-10")); // DISPATCH an ACTION: { type: "saved/lessonSaved", payload: "redux-10" }
// prints: 1Key points
- Store: holds the state. State: the plain data inside it.
- Action: a plain object { type, payload } describing what happened. Action creator: a function that makes one.
- Dispatch: the only way to send an action and change state.
- Reducer: a pure function (state, action) -> new state. Slice: a reducer plus its action creators, from createSlice.
- Selector: a function that reads a piece of state; useSelector runs it in a component.
- Middleware: sees every action first. Thunk: a dispatched function for async work, which dispatches actions itself.
- Name actions as past-tense events ("cart/added") and selectors with select.
Quick check before you move on
Interview questions
Explain store, action, reducer and dispatch in one sentence each.
The store holds the application state; an action is a plain object describing what happened; a reducer is a pure function that computes the next state from the current state and an action; dispatch sends an action to the store, which runs the reducers.
What is a selector, and why use one?
A function that derives data from the state. Selectors keep state-reading logic in one reusable, testable place, hide the state shape from components, and with memoisation avoid unnecessary work and re-renders.
What is middleware in Redux?
A function wrapped around dispatch that sees every action before the reducers. It is where side effects, logging, analytics and async handling such as thunks live.
What is the difference between Redux and Redux Toolkit?
Redux is the core library. Redux Toolkit is the official way to use it: configureStore, createSlice, createAsyncThunk and RTK Query, with Immer for immutable updates and sensible defaults such as DevTools and the thunk middleware.
Quiz
- 1.
What did added("Redux") return in glossary.mjs?
- 2.
After calling the reducer with before = { items: ["Python"] }, was before changed?
- 3.
How many times was the subscriber notified, and why?
- 4.
Does a thunk ever reach a reducer?
- 5.
Which is the better action type: "cart/setItems" or "cart/itemAdded"? Why?
Comments
Sign in to leave a comment. Your name and photo come from Google; nothing else is shared.
Loading comments...
AI
System Design
Backend
- GraphQL8 modules · 69 lessons planned
- Core Python13 modules · 75 lessons planned
- FastAPI5 sections · 20 lessons
- Node.js14 modules · 206 lessons planned
- Node.js Performance7 chapters · 36 topics
- Event Loop Lifecycle6 phases · 3 scenarios
- Docker & Containerization11 modules · 144 lessons planned
- AWS for Developers14 modules · 219 lessons planned
- CI/CD & DevOps Automation10 modules · 134 lessons planned