Error converting content: marked is not a function
title:: Tech / Redux - Redux Toolkit collapsed:: true - Start [here](https://redux.js.org/tutorials/essentials/part-1-overview-concepts) - The **Redux Toolkit** package is intended to be the standard way to write Redux logic. Redux Toolkit includes these APIs: collapsed:: true - [ `configureStore()` ](https://redux-toolkit.js.org/api/configureStore): wraps `createStore` to provide simplified configuration options and good defaults. It can automatically combine your slice reducers, adds whatever Redux middleware you supply, includes `redux-thunk` by default, and enables use of the Redux DevTools Extension. - [ `createReducer()` ](https://redux-toolkit.js.org/api/createReducer): that lets you supply a lookup table of action types to case reducer functions, rather than writing switch statements. In addition, it automatically uses the[ `immer` library](https://github.com/immerjs/immer)to let you write simpler immutable updates with normal mutative code, like `state.todos[3].completed = true` . - [ `createAction()` ](https://redux-toolkit.js.org/api/createAction): generates an action creator function for the given action type string. The function itself has `toString()` defined, so that it can be used in place of the type constant. - [ `createSlice()` ](https://redux-toolkit.js.org/api/createSlice): accepts an object of reducer functions, a slice name, and an initial state value, and automatically generates a slice reducer with corresponding action creators and action types. - [ `createAsyncThunk` ](https://redux-toolkit.js.org/api/createAsyncThunk): accepts an action type string and a function that returns a promise, and generates a thunk that dispatches `pending/fulfilled/rejected` action types based on that promise - [ `createEntityAdapter` ](https://redux-toolkit.js.org/api/createEntityAdapter): generates a set of reusable reducers and selectors to manage normalized data in the store - The[ `createSelector` utility](https://redux-toolkit.js.org/api/createSelector)from the[Reselect](https://github.com/reduxjs/reselect)library, re-exported for ease of use. - The Slice Magic - We know that actions are plain objects with a `type` field, the `type` field is always a string, and we typically have "action creator" functions that create and return the action objects. So where are those action objects, type strings, and action creators defined? - We *could* write those all by hand, every time. But, that would be tedious. Besides, what's *really* important in Redux is the reducer functions, and the logic they have for calculating new state. - Redux Toolkit has a function called `createSlice` , which takes care of the work of generating action type strings, action creator functions, and action object - ** `createSlice` function lets you write immutable updates an easier way!** - `createSlice` uses a library called [Immer](https://immerjs.github.io/immer/) inside. Immer uses a special JS tool called a `Proxy` to wrap the data you provide, and lets you write code that "mutates" that wrapped data. But, **Immer tracks all the changes you've tried to make, and then uses that list of changes to return a safely immutably updated value**, as if you'd written all the immutable update logic by hand. - Updating multiple slices - Usage with typescript collapsed:: true - We infer this bottom up instead of declaring it first top down. - Each slice file should define a type for its initial state value, so that createSlice can correctly infer the type of state in each case reducer. - All generated actions should be defined using the PayloadActiontype from Redux Toolkit, which takes the type of the action.payload field as its generic argument. - You can safely import the RootState type from the store file here. It's a circular import, but the TypeScript compiler can correctly handle that for types. This may be needed for use cases like writing selector functions. - - Define Typed Hooks [](https://redux.js.org/tutorials/typescript-quick-start#define-typed-hooks) - While it's possible to import the `RootState` and `AppDispatch` types into each component, it's **better to create typed versions of the `useDispatch` and `useSelector` hooks for usage in your application**. This is important for a couple reasons: - For `useSelector` , it saves you the need to type `(state: RootState)` every time - For `useDispatch` , the default `Dispatch` type does not know about thunks. In order to correctly dispatch thunks, you need to use the specific customized `AppDispatch` type from the store that includes the thunk middleware types, and use that with `useDispatch` . Adding a pre-typed `useDispatch` hook keeps you from forgetting to import `AppDispatch` where it's needed. Since these are actual variables, not types, it's important to define them in a separate file such as `app/hooks.ts` , not the store setup file. This allows you to import them into any component file that needs to use the hooks, and avoids potential circular import dependency issues. app/hooks.ts ``` import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux' import type { RootState, AppDispatch } from './store' // Use throughout your app instead of plain `useDispatch` and `useSelector` export const useAppDispatch: () => AppDispatch = useDispatch export const useAppSelector: TypedUseSelectorHook = useSelector ``` - Redux 2022+ collapsed:: true - Redux Toolkit standard. - Use hooks vs connect - Put redux stuff in one file instead of all over place - called slice - `createSlice` is the main api for creating reducers - TODO add counter example slice code from https://www.youtube.com/watch?v=9zySeP5vH9c&list=PLz8Iz-Fnk_eTpvd49Sa77NiF8Uqq5Iykx&t=481s - - What are they called reducers? collapsed:: true - The [ `Array.reduce()` ](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce) method lets you take an array of values, process each item in the array one at a time, and return a single final result. You can think of it as "reducing the array down to one value". `Array.reduce()` takes a callback function as an argument, which will be called one time for each item in the array. It takes two arguments: - `previousResult` , the value that your callback returned last time - `currentItem` , the current item in the array The first time that the callback runs, there isn't a `previousResult` available, so we need to also pass in an initial value that will be used as the first `previousResult`. - **A Redux reducer function is exactly the same idea as this "reduce callback" function!** It takes a "previous result" (the `state` ), and the "current item" (the `action` object), decides a new state value based on those arguments, and returns that new state. - If we were to create an array of Redux actions, call `reduce()` , and pass in a reducer function, we'd get a final result the same way: - ``` const actions = [ { type: 'counter/increment' }, { type: 'counter/increment' }, { type: 'counter/increment' } ] - const initialState = { value: 0 } - const finalResult = actions.reduce(counterReducer, initialState) console.log(finalResult) // {value: 3} ``` - ==**Redux reducers reduce a set of actions (over time) into a single state**.== #nice - The difference is that with `Array.reduce()` it happens all at once, and with Redux, it happens over the lifetime of your running app. - The app state management is then a stream of events that get reduced to app states