Fullstack CourseLearn by building
Back to week 2

Topic

Redux Toolkit — official tutorial path

Definition

Redux Toolkit is the standard way to write Redux. The official Tutorials Overview tells you which tutorial to read for which goal: Quick Start to wire an app, Essentials to build something real, Fundamentals to understand why the patterns exist.

In simpler words

Do not learn RTK by memorizing every API. Follow the Redux team’s order: get a counter working, then build a feature, then peek under the hood.

This course lesson mirrors https://redux-toolkit.js.org/tutorials/overview and the Quick Start steps, then maps them onto this monorepo (Next + TypeScript + Nest).

After this you can

  • Pick the right official tutorial for your goal
  • Follow the Quick Start recipe end-to-end
  • Wire TypeScript RootState / AppDispatch hooks
  • Place Provider correctly in a Next.js app
  • Know what Essentials vs Fundamentals teach next

0. How the Redux team wants you to learn

The RTK Tutorials Overview page says the deep tutorials live on redux.js.org, and RTK docs point there instead of duplicating everything.

Quick Start — fastest way to add RTK + React-Redux and use the main APIs. Start here if you just need it running.

TypeScript Quick Start — same wiring with RootState / AppDispatch patterns.

Next.js tutorial — how Provider fits an App Router app (client boundary).

Redux Essentials — “how do I use this to build something useful?” Real-world style app. Best if you are new to Redux.

Redux Fundamentals — bottom-up: write Redux by hand, then see why RTK wraps it. Best when you want the “why”.

Usage Guide + API Reference — look up each API when you need details. Usage with TypeScript for TS patterns. RTK Query Quick Start when you need Redux-powered fetching.

Pick your path

Need it working tonight  → Quick Start (this lesson §1–§4)
New to Redux             → Essentials on redux.js.org
Want the “why”           → Fundamentals on redux.js.org
Using Next + TS (here)   → §5 below + our AppProviders
Need server cache in RTK → RTK Query Quick Start (later topic)
Migrating old Redux      → “Modern Redux with RTK” in Fundamentals

Source: https://redux-toolkit.js.org/tutorials/overview

1. Quick Start — install

Quick Start step one: add @reduxjs/toolkit and react-redux.

This monorepo already has both in apps/web.

Install

pnpm add @reduxjs/toolkit react-redux

Toolkit = store tools. react-redux = Provider + hooks.

Mistake: Toolkit only

pnpm add @reduxjs/toolkit
// components still cannot use useSelector / useDispatch

You need react-redux for React bindings.

2. Quick Start — create the store

Create a store with configureStore. Even an empty reducer object is valid to start; DevTools are enabled by default.

Infer RootState and AppDispatch from the store — that is the TypeScript Quick Start pattern.

Empty store (then add slices)

import { configureStore } from "@reduxjs/toolkit";

export const store = configureStore({
  reducer: {},
});

export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

From the official Quick Start / TS Quick Start.

3. Quick Start — create a slice, then register it

createSlice needs: name, initialState, reducers. It generates action creators and the slice reducer.

You may write “mutating” updates inside reducers — Immer turns them into immutable updates (see also “Writing Reducers with Immer” in the RTK docs).

Put the slice reducer on the store under a key (counter, notesDraft, …).

Counter slice (Quick Start example)

import { createSlice, type PayloadAction } from "@reduxjs/toolkit";

type CounterState = { value: number };
const initialState: CounterState = { value: 0 };

export const counterSlice = createSlice({
  name: "counter",
  initialState,
  reducers: {
    increment(state) {
      state.value += 1;
    },
    decrement(state) {
      state.value -= 1;
    },
    incrementByAmount(state, action: PayloadAction<number>) {
      state.value += action.payload;
    },
  },
});

export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;

// store.ts
import counterReducer from "./features/counter/counterSlice";
export const store = configureStore({
  reducer: { counter: counterReducer },
});

Same shape as the official counter Quick Start — then swap counter for your feature.

Mistake: forget to add the reducer to the store

// Slice exists, but store still has reducer: {}
// useSelector(s => s.counter) is undefined

Register every slice reducer in configureStore.

4. Quick Start — Provider + useSelector / useDispatch

Wrap the app in <Provider store={store}>.

Read with useSelector; write with dispatch(increment()). When the store updates, subscribed components re-render.

That is the whole daily loop from the Quick Start “What You’ve Learned” summary.

Component usage

import { useSelector, useDispatch } from "react-redux";
import type { RootState, AppDispatch } from "./store";
import { increment, decrement } from "./counterSlice";

export function Counter() {
  const count = useSelector((state: RootState) => state.counter.value);
  const dispatch = useDispatch<AppDispatch>();
  return (
    <div>
      <button type="button" onClick={() => dispatch(increment())}>+</button>
      <span>{count}</span>
      <button type="button" onClick={() => dispatch(decrement())}>-</button>
    </div>
  );
}

Click → dispatch → reducer → new state → re-render.

Typed hooks (TypeScript Quick Start)

import { useDispatch, useSelector, type TypedUseSelectorHook } from "react-redux";
import type { RootState, AppDispatch } from "./store";

export const useAppDispatch: () => AppDispatch = useDispatch;
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

// then: useAppSelector(s => s.counter.value)

Export the same typed hooks from your feature store module.

5. Next.js + this monorepo

Tutorials Overview links a Next.js-specific RTK setup. In the App Router, Provider must live in a Client Component.

Here: apps/web/src/components/providers/app-providers.tsx currently wraps QueryClientProvider. Add a Redux Provider the same way when a feature needs a client draft store (Week 4 Notes projects).

Do not put the store in a Server Component. Do not create a new store on every render without care — use useState(() => makeStore()).

AppProviders sketch (when you add RTK)

"use client";
import { Provider as ReduxProvider } from "react-redux";
import { makeStore } from "@/features/notes/notesDraftStore";

export function AppProviders({ children }) {
  const [store] = useState(() => makeStore());
  return <ReduxProvider store={store}>{children}</ReduxProvider>;
}

Matches the Next guidance: client Provider around the tree.

6. After Quick Start — Essentials, Fundamentals, Usage Guide

Essentials (redux.js.org): build a realistic feature flow with RTK as the default. The next topic (client drafts) plus Week 4 Notes projects are the course’s Essentials-style practice.

Fundamentals (redux.js.org): hand-written actions/reducers first, then see how createSlice / configureStore replace the boilerplate. Read this when “why Immer / why one store?” still feels fuzzy.

Usage Guide: per-API patterns. API Reference: exact signatures. Writing Reducers with Immer: deep dive on draft state.

RTK Query Quick Start: when you need fetching inside Redux — covered in the RTK Query vs TanStack topic (this repo prefers TanStack for Nest).

Course mapping

Official Quick Start     → this topic §§1–4
Official Essentials      → rtk-client-drafts + Week 4 Notes projects
Official Fundamentals    → optional homework on redux.js.org
Official RTK Query QS    → rtk-vs-query topic
Official Usage Guide     → when you need createAsyncThunk / entityAdapter details

Stay on the official rails; this lesson is the on-ramp.

7. Toolbox reminder (from Getting Started)

Daily: createSlice, configureStore, Provider, useSelector, useDispatch.

Also in the box: createAsyncThunk, createEntityAdapter, createSelector, combineSlices, createAction/createReducer, RTK Query createApi.

You do not need every tool on day one — Quick Start is enough to be productive.

When not to use RTK

// Local button open/closed → useState
// Nest list data → TanStack Query
// Shared wizard draft → RTK createSlice

Same ownership rule as before — now with the official learning path behind it.

Live playground

Quick Start counter sandbox

Dispatch increment / amount / reset like the official counter.

Mini createSlice feel: dispatch named actions → state updates → UI re-renders.

value=0 · title="(empty)"

createSlice → configureStore → Provider → dispatch(action)

Keep in mind

  • Tutorials Overview: https://redux-toolkit.js.org/tutorials/overview
  • Quick Start: https://redux-toolkit.js.org/tutorials/quick-start
  • Then Essentials / Fundamentals on https://redux.js.org
  • Apply Provider + slice in Week 4 Notes UI projects.

Test

Check your understanding

At least 10 questions — mix of concept, syntax, practical, and logic. Score ≥ 80% (enforced by the API) to save progress.

Checking your session…

12 questions · concept 4 · syntax 3 · practical 3 · logic 2

Concept1. According to the RTK Tutorials Overview, which tutorial is the fastest way to get a basic RTK + React example running?
Concept2. If you have never used Redux and want to build something useful with RTK, which tutorial does Tutorials Overview recommend first?
Syntax3. Which API is the everyday way to define state + reducers + action creators together?
Syntax4. Which API creates the store with good defaults (DevTools, thunk middleware)?
Practical5. Inside a createSlice reducer, why can you write state.value += 1?
Practical6. What is the usual React wiring order?
Logic7. Which RTK helper manages normalized ids + entities maps?
Logic8. What does createAsyncThunk help with?
Concept9. What is createSelector for?
Syntax10. Which APIs are lower-level building blocks you rarely start with?
Practical11. In this academy, where should the Nest tickets list primarily live?
Concept12. What optional RTK addon fetches and caches server data inside Redux?