Advanced Redux with Redux Toolkit
Table of Contents
IntroductionSteve Kinney begins the Advanced Redux course by talking through some of the production challenges developers face with state management. The course projects are introduced, and links to each repository are provided.
Create SliceSteve introduces Redux slices. The createSlice method accepts an initial state, an object of reducer functions, and a slice name. Action creators and action types corresponding to the reducers and state are automatically generated.
Create ActionSteve uses the createAction helper method to combine the declaration of an action type and an action creator. The action creator can be called with or without arguments or with a payload attached to the action.
Create Action ExerciseStudents are instructed to refactor the counter.ts file to use the createAction method. Use the create-action-exercise branch to begin. The solution for this exercise can be found on the create-exercise-solution branch.
Create ReducerSteve demonstrates how the createReducer helper method simplifies the process of creating reducers. Builder callback functions that define the cases for each action are passed to the reduce. Mutable operations can be performed on the state object because the underlying libraries create a "WriteableDraft" of the state.
Create Reducer ExerciseStudents are instructed to use createReducer for the decrement and reset actions. Use the create-reducer-exercise branch to begin. The solution can be found on the create-reducer-solution branch.
Redux Toolkit StoreSteve switches back to the Super Tasker application to demonstrate how to add a store with Redux Toolkit. The configureStore method applies the tasksReducer to the store. A Provider is then wrapped around the Application component.
Partial Types for Incomplete DataSteve uses Partial Types to eliminate TypeScript errors for missing properties and keep business logic inside the reducer and away from the view layer. Partial Types make all properties optional. A utility function is used to hydrate the missing properties on an object before it's pushed into the state.
Utility Type for Incomplete DataSteve uses Utility Types to demonstrate an alternative method for handling incomplete data. A RequireOnly type is created with TypeScript generics. The resulting type allows required properties to be specified and any remaining types to be optional
Typed useSelector HookSteve demonstrates one method for adding type support to the useSelector Hook. An ApplicationState type is declared and exported from the store. The drawback to this approach is the type must be imported anywhere the useSelector hook is used.
Typed Custom Hook for useSelectorSteve demonstrates an alternate approach for adding type support to the useSelector hook. A custom hook for useSelector is created and typed using the TypedUseSelectorHook utility type.
Typed Custom Hook for useDispatchSteve adds type support to the useDispatch hook. A custom hook is created to apply the type. The Redux DevTools extension is also demonstrated in this lesson.
Implementing User Slice ExerciseStudents are instructed to implement the User Slice. To begin the exercise, check out the user-slice-exercise branch. The solution can be found on the user-slice-solution branch.
Unit Testing ReduxSteve writes unit tests for testing slices in the application. The slice methods are imported. The initial state is defined, and the actions in each slice are tested.
Extra ReducersSteve uses the extraReducers property to add dependent actions to a slice. This is useful for clean-up tasks such as removing any items associated with a user when the user account is removed.
Async Requests with createAsyncThunkSteve introduces creatAsyncThunk, a function that accepts a Redux action type string and a callback function that should return a promise. The thunk action creator it returns can be used by the extraReducers builder in a slice.
fetchTasks Pending StateSteve handles the pending state for the asynchronous request. A loading property is added to the state. The builder adds the additional case to the extraReducers property.
Custom Hooks for Async RequestsSteve creates a useTasks custom hook that returns the array of Tasks and a boolean value representing whether or not the data is loading. This hook is added to the TaskList component, and the loading property is bound to the Loading component.
API Service with RTK QuerySteve wires up RTK Query in the packing list application. An API service is created with the createService method, and a builder object is passed to the endpoints property to establish the server methods. A store is configured, and the new API service is concatenated to the default middleware.
Using Custom Hooks from Redux ToolkitSteve demonstrates the custom hooks that Redux Toolkit automatically generates from services created with the createAPI method. This makes it possible for the service to be integrated with a Redux application or agnostically with any other infrastructure.