new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Redux Toolkit · API · all subjects

otherexports

103 notes in this subject, read out of this brain and free to use. This is page 1 of 2.

miniSerializeError function signature and interface

miniSerializeError is the default error serialization function used by createAsyncThunk, based on serialize-error. It takes any value as an argument. If the argument is an object such as an Error instance, it returns a plain JS SerializedError object that copies over the listed fields (name, message, stack, code). Otherwise, it returns a stringified form of the value as { message: String(value) }. interface SerializedError { name?: string message?: string stack?: string code?: string } function miniSerializeError(value: any): SerializedError

copyWithStructuralSharing function signature and behavior

copyWithStructuralSharing is a utility that recursively merges two similar objects together, preserving existing references if the values appear to be the same. It is used internally to help ensure that re-fetched data keeps using the same references unless the new data has actually changed, avoiding unnecessary re-renders. If either input is not a plain JS object or array, the new value is returned. function copyWithStructuralSharing<T>(oldObj: any, newObj: T): T function copyWithStructuralSharing(oldObj: any, newObj: any): any

createNextState - re-export of immer produce function

createNextState is the default immutable update function from the immer library, re-exported from Redux Toolkit. It is also commonly referred to as produce.

nanoid example usage

import { nanoid } from '@reduxjs/toolkit' console.log(nanoid()) // 'dgPXxUz_6fWIQBD8XmiSy'

current function from immer - snapshot state during draft

current is a function from the immer library. It takes a snapshot of the current state of a draft and finalizes it without freezing. It is useful for printing the current state during debugging. The output of current can be safely leaked outside the producer.

current function example usage

import { createReducer, createAction, current } from '@reduxjs/toolkit' interface Todo { //... } const addTodo = createAction<Todo>('addTodo') const initialState = [] satisfies Todo[] as Todo[] const todosReducer = createReducer(initialState, (builder) => { builder.addCase(addTodo, (state, action) => { state.push(action.payload) console.log(current(state)) }) })

original function from immer - returns original object

original is a function from the immer library. It returns the original object. It is particularly useful for referential equality checks in reducers.

isDraft function from immer - checks if value is draft

isDraft is a function from the immer library. It checks whether a given value is a Proxy-wrapped draft state.

freeze function from immer - freezes draftable objects

freeze is a function from the immer library. It freezes draftable objects using the same mechanism as Object.freeze.

combineReducers - Redux re-export for convenience

combineReducers is Redux's combineReducers function, re-exported from Redux Toolkit for convenience. While configureStore calls this internally, you may wish to call it directly to compose multiple levels of slice reducers.

compose - Redux function composing functions right to left

compose is Redux's compose function. It composes functions from right to left. It is a functional programming utility. You might want to use it to apply several store custom enhancers or functions in a row.

bindActionCreators - Redux re-export for wrapping action creators

bindActionCreators is Redux's bindActionCreators function. It wraps action creators with dispatch() so that they dispatch immediately when called.

createStore - Redux re-export, not recommended for direct use

createStore is Redux's createStore function. It is re-exported from Redux Toolkit but you should not need to use it directly.

applyMiddleware - Redux re-export, not recommended for direct use

applyMiddleware is Redux's applyMiddleware function. It is re-exported from Redux Toolkit but you should not need to use it directly.

nanoid function - generates random ID

nanoid is an inlined copy of nanoid/nonsecure. It generates a non-cryptographically-secure random ID string. It is used by default by createAsyncThunk for request IDs and may be useful for other cases.

Serializability Middleware purpose

The serializability middleware is a custom middleware that detects if any non-serializable values have been included in state or dispatched actions, modeled after redux-immutable-state-invariant. Any detected non-serializable values will be logged to the console.

Serializability Middleware included by default

The serializability middleware is added to the store by default by configureStore and getDefaultMiddleware.

SerializableStateInvariantMiddlewareOptions interface

The SerializableStateInvariantMiddlewareOptions interface has the following properties: isSerializable (function, optional, defaults to isPlain(), checks if a value is serializable and applies recursively); getEntries (function, optional, defaults to undefined, retrieves entries from each value); ignoredActions (string array, optional, defaults to [], action types to ignore when checking serializability); ignoredActionPaths (string or RegExp array, optional, defaults to ['meta.arg', 'meta.baseQueryMeta'], dot-separated path strings or regexes to ignore); ignoredPaths (string or RegExp array, optional, defaults to [], dot-separated path strings or regexes to ignore); warnAfter (number, optional, defaults to 32ms, execution time warning threshold); ignoreState (boolean, optional, opts out of checking state); ignoreActions (boolean, optional, opts out of checking actions).

createSerializableStateInvariantMiddleware function

createSerializableStateInvariantMiddleware creates an instance of the serializability check middleware with the given options. It takes a SerializableStateInvariantMiddlewareOptions object as an argument and returns middleware. This function is typically used via getDefaultMiddleware and does not usually need to be called directly.

isPlain function

isPlain checks whether the given value is considered a 'plain value' or not. It returns true for undefined, null, strings, booleans, numbers, arrays, and plain objects. It returns false for Date objects, Map objects, and other similar class instances.

createSerializableStateInvariantMiddleware example with Immutable.JS

Example showing how to create a serializable middleware instance that treats Immutable.JS iterables as serializable: import { Iterable } from 'immutable'; import { configureStore, createSerializableStateInvariantMiddleware, isPlain, Tuple } from '@reduxjs/toolkit'; import reducer from './reducer'; const isSerializable = (value: any) => Iterable.isIterable(value) || isPlain(value); const getEntries = (value: any) => Iterable.isIterable(value) ? value.entries() : Object.entries(value); const serializableMiddleware = createSerializableStateInvariantMiddleware({ isSerializable, getEntries }); const store = configureStore({ reducer, middleware: () => new Tuple(serializableMiddleware) });

One API slice per base URL recommendation

Best practice is to have only one API slice per base URL that the application needs to communicate with. For example, if fetching from both /api/posts and /api/users, create a single API slice with /api/ as the base URL and separate endpoint definitions for posts and users.

RTK Query is built on Redux Toolkit core

RTK Query is built on top of the Redux Toolkit core and leverages RTK APIs like createSlice and createAsyncThunk to implement its capabilities.

RTK Query included in redux-toolkit package

RTK Query is included in the @reduxjs/toolkit package as an additional addon. It is not required to use RTK Query APIs when using Redux Toolkit.

createApi basic usage for RTK Query

createApi is used to define an RTK Query service. Example: export const pokemonApi = createApi({ reducerPath: 'pokemonApi', baseQuery: fetchBaseQuery({ baseUrl: 'https://pokeapi.co/api/v2/' }), endpoints: (builder) => ({ getPokemonByName: builder.query<Pokemon, string>({ query: (name) => `pokemon/${name}`, }), }), });

fetchBaseQuery used with createApi

fetchBaseQuery is used to configure the base URL and other fetch options when creating an RTK Query API service. It is imported from '@reduxjs/toolkit/query/react'.

RTK Query generates auto-generated React hooks

RTK Query automatically generates React hooks based on the defined endpoints. These hooks are exported from the API service definition and can be used in functional components.

setupListeners for RTK Query refetch behaviors

setupListeners must be called to enable refetchOnFocus and refetchOnReconnect behaviors in RTK Query. It is imported from '@reduxjs/toolkit/query' and called with store.dispatch.

Query hook return values

RTK Query query hooks return an object containing: data (the fetched data), error (any error that occurred), isLoading (boolean indicating if initial request is in progress), isFetching (boolean indicating if any request is in progress), isSuccess (boolean indicating successful completion), and isError (boolean indicating an error occurred).

RTK Query dedupes requests automatically

RTK Query automatically deduplicates requests across components subscribing to the same query, ensuring the same data is used and performance optimizations are handled automatically.

injectEndpoints for code splitting RTK Query

The injectEndpoints property can be used to inject API endpoints from other files into a single API slice definition for maintainability purposes while keeping a centralized API slice.

original and isDraft functions re-exported from RTK

Redux Toolkit re-exports Immer's original and isDraft functions as of RTK 1.5.1. The original function retrieves the original data without any updates applied, and isDraft checks if a given value is a Proxy-wrapped draft.

Standalone getDefaultMiddleware and getType exports removed

In Redux Toolkit 2.0, the standalone getDefaultMiddleware export has been removed. Use the function passed to the middleware callback instead. The getType export has also been removed; use actionCreator.type static property instead.

action.type must be a string

In Redux 5.0, action.type must be a string. Attempting to dispatch an action with a non-string type will throw an error. This ensures actions are serializable and provide readable action history in Redux DevTools.

RTK Query API reducer and middleware must be added to store

When using RTK Query, the generated API object's reducer must be added to configureStore under the API's reducerPath key, and the API's middleware must be added to the middleware chain using concat() method.

useSelector hook replaces connect mapStateToProps

React-Redux useSelector hook is used instead of connect's mapStateToProps to select values from state. Each field from mapStateToProps becomes a separate useSelector call inside the component.

useDispatch hook replaces connect mapDispatchToProps

React-Redux useDispatch hook is used instead of connect's mapDispatchToProps to get the dispatch function. Action dispatching is done with callback functions defined inside the component that call dispatch with action creators.

React.memo prevents unnecessary re-renders with hooks

Unlike connect which prevents re-renders when props haven't changed, useSelector and useDispatch hooks are inside components so they cannot prevent React's normal rendering behavior. Wrap components with React.memo() to prevent unnecessary re-renders when parent components re-render.

Prefer RTK Query over createAsyncThunk for data fetching

Redux Toolkit documentation specifically recommends using RTK Query for data fetching rather than createAsyncThunk, as RTK Query provides a more complete solution with built-in caching and state management.

Infer AppDispatch type from store.dispatch

For TypeScript, infer the AppDispatch type by using typeof store.dispatch which correctly includes types for middleware-added functionality like thunks and other dispatch enhancements.

Create pre-typed useAppDispatch and useAppSelector hooks

For TypeScript, create pre-typed hook aliases using useDispatch.withTypes<AppDispatch>() and useSelector.withTypes<RootState>() and use these throughout the app instead of plain hooks to ensure correct types everywhere.

Legacy action type unions pattern should be avoided

Redux Toolkit documentation specifically recommends against manually defining types for individual actions and creating 'action type unions' to limit what can be dispatched. This pattern was common in legacy TypeScript Redux code but is unnecessarily verbose.

Modern Redux uses feature-based folder organization

Redux Toolkit and modern Redux patterns recommend organizing files by 'features' with related code living together in the same folder, rather than the older pattern of organizing by 'type of code' (actions, reducers, constants in separate folders).

Action names should use past tense event-style descriptions

Modern Redux patterns recommend naming actions in past tense using event-style names that describe 'a thing that happened', such as 'todoAdded' instead of imperative names like 'ADD_TODO'.

Start Redux migration by replacing createStore with configureStore

When migrating legacy Redux code to modern patterns, always start by replacing the legacy createStore call with configureStore. This is a one-time step that allows existing reducers and middleware to continue working while enabling development-mode checks for common mistakes.

Migrate legacy Redux incrementally, slice by slice

Legacy Redux codebases can be modernized incrementally by replacing one reducer and its actions at a time with createSlice, allowing old and new Redux code to coexist and work together.

Infer RootState type from store.getState return type

For TypeScript, infer the RootState type by using ReturnType<typeof store.getState> which automatically includes all slice state types and reflects any modifications to slice definitions.

RTK Query replaces data fetching boilerplate

Redux Toolkit's RTK Query is a data fetching and caching layer that eliminates the need to manually write actions, thunks, reducers, and selectors for data fetching. It handles loading state tracking, request deduplication, and cache lifecycle management internally.

RTK Query createApi defines endpoints and generates hooks

createApi accepts configuration with baseQuery and endpoints. Endpoints are defined as query or mutation operations. The API object exposes generated React hooks for each endpoint with naming pattern useEndpointNameQuery or useEndpointNameMutation.

SerializableStateInvariantMiddlewareOptions interface

SerializableStateInvariantMiddlewareOptions has properties: getEntries (optional, (value: any) => [string, any][]), ignoredActionPaths (optional, (string | RegExp)[]), ignoredActions (optional, string[]), ignoredPaths (optional, (string | RegExp)[]), ignoreState (optional, boolean), isSerializable (optional, (value: any) => boolean), warnAfter (optional, number).

nanoid export

nanoid is an exported function with signature: (size?: number) => string. Generates a unique ID string.

unwrapResult function

unwrapResult<R extends UnwrappableAction>(action: R): UnwrappedActionPayload<R>. Extracts the payload from an async thunk result, throwing if the action was rejected.

EnhancedStore interface

EnhancedStore<S, A, M> extends Store<S, A> and has dispatch property of type Dispatch<A> & DispatchForMiddlewares<M>.

createAction function signature with prepare

createAction has two overloads: (1) createAction<P = void, T extends string = string>(type: T): PayloadActionCreator<P, T>, and (2) createAction<PA extends PrepareAction<any>, T extends string = string>(type: T, prepareAction: PA): PayloadActionCreator<ReturnType<PA>['payload'], T, PA>.

PayloadAction type structure

PayloadAction<P = void, T extends string = string, M = never, E = never> is an object with payload: P and type: T, optionally including meta: M (if M is not never) and error: E (if E is not never).

PayloadActionCreator type definition

PayloadActionCreator<P, T, PA> is determined by whether PA is provided (uses _ActionCreatorWithPreparedPayload<PA, T>) or by the type of P: any uses ActionCreatorWithPayload<any, T>, unknown or non-inferrable uses ActionCreatorWithNonInferrablePayload<T>, void uses ActionCreatorWithoutPayload<T>, optional uses ActionCreatorWithOptionalPayload<P, T>, otherwise ActionCreatorWithPayload<P, T>.

PrepareAction type

PrepareAction<P> is one of: (...args: any[]) => {payload: P}, (...args: any[]) => {payload: P, meta: any}, (...args: any[]) => {payload: P, error: any}, or (...args: any[]) => {payload: P, meta: any, error: any}.

CaseReducer type

CaseReducer<S = any, A extends Action = UnknownAction> is a function with signature: (state: Draft<S>, action: A) => S | void | Draft<S>.

ActionReducerMapBuilder interface methods

ActionReducerMapBuilder<State> has methods: addCase (with two overloads: accepts ActionCreator with CaseReducer, or accepts Type string with CaseReducer), addMatcher (accepts TypeGuard<A> or boolean function with CaseReducer, returns Omit<ActionReducerMapBuilder<State>, 'addCase'>), addDefaultCase (accepts CaseReducer<State, UnknownAction>, returns {}).

miniSerializeError constant

miniSerializeError is an exported function that serializes error values: (value: any) => SerializedError.

Give your agent this brain