CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-reduxjs--toolkit

The official, opinionated, batteries-included toolset for efficient Redux development

Pending
Overview
Eval results
Files

core-store.mddocs/

Store Configuration

Redux Toolkit's store configuration provides a simplified API over Redux's createStore() with sensible defaults, automatic middleware setup, and enhanced developer experience features.

Capabilities

Configure Store

Creates a Redux store with good defaults including Redux Thunk, Redux DevTools integration, and development-time invariant checking middleware.

/**
 * A friendly abstraction over Redux's createStore() with good defaults
 * @param options - Configuration options for the store
 * @returns Enhanced Redux store with thunk support and additional methods
 */
function configureStore<
  S = any,
  A extends Action = AnyAction,
  M extends Middlewares<S> = Middlewares<S>,
  E extends Enhancers = Enhancers
>(options: ConfigureStoreOptions<S, A, M, E>): EnhancedStore<S, A, E>;

interface ConfigureStoreOptions<S, A extends Action, M extends Middlewares<S>, E extends Enhancers, P = S> {
  /** Root reducer or reducer map object */
  reducer: Reducer<S, A> | ReducersMapObject<S, A>;
  /** Callback to customize middleware array (receives getDefaultMiddleware) */
  middleware?: ((getDefaultMiddleware: GetDefaultMiddleware<S>) => M) | M;
  /** Enable Redux DevTools (default: true in development) */
  devTools?: boolean | DevToolsOptions;
  /** Initial state value */
  preloadedState?: P;
  /** Callback to customize store enhancers */
  enhancers?: ((getDefaultEnhancers: GetDefaultEnhancers<S>) => E) | E;
}

interface EnhancedStore<S = any, A extends Action = AnyAction, E = any> extends Store<S, A> {
  /** Dispatch function with thunk support */
  dispatch: Dispatch<A> & ThunkDispatch<S, any, A>;
}

Usage Examples:

import { configureStore } from '@reduxjs/toolkit';
import counterSlice from './features/counter/counterSlice';
import todosSlice from './features/todos/todosSlice';

// Basic store setup
const store = configureStore({
  reducer: {
    counter: counterSlice.reducer,
    todos: todosSlice.reducer
  }
});

// Custom middleware configuration
const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: ['persist/PERSIST']
      }
    }).concat(logger),
  devTools: process.env.NODE_ENV !== 'production'
});

// With preloaded state
const store = configureStore({
  reducer: rootReducer,
  preloadedState: {
    counter: { value: 5 },
    todos: []
  }
});

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

Default Middleware

Get the default middleware array that includes Redux Thunk and development-time checking middleware.

/**
 * Returns the default middleware array used by configureStore
 * @param options - Options to customize the default middleware
 * @returns Array of middleware functions
 */
interface GetDefaultMiddleware<S> {
  <O extends MiddlewareOptions<S>>(options?: O): Tuple<DefaultMiddlewareArray<S, O>>;
}

interface MiddlewareOptions<S> {
  /** Enable thunk middleware (default: true) */
  thunk?: boolean | ThunkOptions<S>;
  /** Enable immutable state invariant middleware (default: true in development) */
  immutableCheck?: boolean | ImmutableStateInvariantMiddlewareOptions;
  /** Enable serializable state invariant middleware (default: true in development) */
  serializableCheck?: boolean | SerializableStateInvariantMiddlewareOptions;
  /** Enable action creator invariant middleware (default: true in development) */
  actionCreatorCheck?: boolean | ActionCreatorInvariantMiddlewareOptions;
}

type DefaultMiddlewareArray<S, O extends MiddlewareOptions<S>> = [
  ThunkMiddleware<S>,
  ...ConditionalMiddleware<O['immutableCheck'], ImmutableStateInvariantMiddleware<S>>,
  ...ConditionalMiddleware<O['serializableCheck'], SerializableStateInvariantMiddleware>,
  ...ConditionalMiddleware<O['actionCreatorCheck'], ActionCreatorInvariantMiddleware>
];

Usage Examples:

import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import logger from 'redux-logger';

// Add custom middleware to defaults
const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware()
      .prepend(
        // Correctly typed middleware can be added before
        rateLimitMiddleware({ requests: 5, window: 1000 })
      )
      .concat(
        // And after the defaults
        logger
      )
});

// Customize default middleware options
const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      thunk: {
        extraArgument: { api, analytics }
      },
      serializableCheck: {
        ignoredActions: ['persist/PERSIST', 'persist/REHYDRATE']
      }
    })
});

// Disable development middleware in production
const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      immutableCheck: process.env.NODE_ENV !== 'production',
      serializableCheck: process.env.NODE_ENV !== 'production'
    })
});

Store Enhancers

Configure store enhancers for additional functionality like persistence or analytics.

/**
 * Get default store enhancers (auto-batching by default)
 * @param options - Options to customize enhancers
 * @returns Array of store enhancers
 */
interface GetDefaultEnhancers<S> {
  <O extends EnhancerOptions>(options?: O): Tuple<DefaultEnhancerArray<S, O>>;
}

interface EnhancerOptions {
  /** Enable auto-batching enhancer (default: true) */
  autoBatch?: boolean | AutoBatchOptions;
}

type DefaultEnhancerArray<S, O extends EnhancerOptions> = [
  ...ConditionalEnhancer<O['autoBatch'], AutoBatchEnhancer>
];

/** Store enhancer for automatic action batching */
function autoBatchEnhancer(options?: AutoBatchOptions): StoreEnhancer;

interface AutoBatchOptions {
  /** Custom batch type checker */
  type?: 'tick' | 'timer' | 'callback' | ((action: Action) => boolean);
}

Usage Examples:

import { configureStore, autoBatchEnhancer } from '@reduxjs/toolkit';
import { persistStore, persistReducer } from 'redux-persist';

// Add persistence enhancer
const persistConfig = {
  key: 'root',
  storage,
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

const store = configureStore({
  reducer: persistedReducer,
  enhancers: (getDefaultEnhancers) =>
    getDefaultEnhancers().concat(
      // Add your custom enhancers here
    )
});

// Custom auto-batching configuration
const store = configureStore({
  reducer: rootReducer,
  enhancers: (getDefaultEnhancers) =>
    getDefaultEnhancers({
      autoBatch: { type: 'tick' }
    })
});

Development Middleware

Redux Toolkit includes several development-time middleware for catching common mistakes.

/**
 * Middleware that detects mutations to state
 * @param options - Configuration options
 * @returns Middleware function
 */
function createImmutableStateInvariantMiddleware<S = any>(
  options?: ImmutableStateInvariantMiddlewareOptions
): Middleware<{}, S>;

interface ImmutableStateInvariantMiddlewareOptions {
  /** Enable the middleware */
  isImmutable?: (value: any) => boolean;
  /** Paths to ignore when checking for mutations */
  ignoredPaths?: string[];
  /** Function to determine if checking should be ignored */
  warnAfter?: number;
}

/**
 * Middleware that detects non-serializable values in state and actions
 * @param options - Configuration options
 * @returns Middleware function
 */
function createSerializableStateInvariantMiddleware(
  options?: SerializableStateInvariantMiddlewareOptions
): Middleware<{}, any>;

interface SerializableStateInvariantMiddlewareOptions {
  /** Actions to ignore when checking */
  ignoredActions?: string[];
  /** Action paths to ignore */
  ignoredActionPaths?: string[];
  /** State paths to ignore */
  ignoredPaths?: string[];
  /** Function to determine if value is serializable */
  isSerializable?: (value: any) => boolean;
  /** Function to get entries from value for checking */
  getEntries?: (value: any) => [string, any][];
  /** Execution time warning threshold */
  warnAfter?: number;
}

/**
 * Middleware that validates action creators are not called incorrectly
 * @param options - Configuration options
 * @returns Middleware function
 */
function createActionCreatorInvariantMiddleware(
  options?: ActionCreatorInvariantMiddlewareOptions
): Middleware;

interface ActionCreatorInvariantMiddlewareOptions {
  /** Enable the middleware */
  isActionCreator?: (action: any) => boolean;
}

Usage Examples:

import { 
  configureStore,
  createImmutableStateInvariantMiddleware,
  createSerializableStateInvariantMiddleware
} from '@reduxjs/toolkit';

const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      // Configure immutable check
      immutableCheck: {
        ignoredPaths: ['items.dates'],
        warnAfter: 128
      },
      // Configure serializable check
      serializableCheck: {
        ignoredActions: ['persist/PERSIST', 'persist/REHYDRATE'],
        ignoredPaths: ['items.map'],
        warnAfter: 128
      }
    })
});

Store Types

Enhanced Store Interface

/**
 * Extended Redux store with additional typing for thunk dispatch
 */
interface EnhancedStore<S = any, A extends Action = AnyAction, E = any> extends Store<S, A> {
  dispatch: Dispatch<A> & ThunkDispatch<S, any, A>;
}

/**
 * Configuration options for configureStore
 */
interface ConfigureStoreOptions<S, A extends Action, M extends Middlewares<S>, E extends Enhancers, P = S> {
  reducer: Reducer<S, A> | ReducersMapObject<S, A>;
  middleware?: ((getDefaultMiddleware: GetDefaultMiddleware<S>) => M) | M;
  devTools?: boolean | DevToolsOptions;
  preloadedState?: P;
  enhancers?: ((getDefaultEnhancers: GetDefaultEnhancers<S>) => E) | E;
}

/**
 * Redux DevTools configuration options
 */
interface DevToolsOptions {
  /** Custom action name mapping */
  actionCreators?: ActionCreatorMapObject;
  /** Maximum number of actions to keep */
  maxAge?: number;
  /** Actions to skip in DevTools */
  actionSanitizer?: (action: Action, id: number) => Action;
  /** State sanitizer for DevTools */
  stateSanitizer?: <S>(state: S, index: number) => S;
  /** Trace option */
  trace?: boolean;
  /** Trace limit */
  traceLimit?: number;
}

Best Practices

Store Organization

// store/index.ts - Main store configuration
import { configureStore } from '@reduxjs/toolkit';
import { rootReducer } from './rootReducer';

export const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: ['persist/PERSIST', 'persist/REHYDRATE']
      }
    })
});

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

// store/rootReducer.ts - Combined reducers
import { combineReducers } from '@reduxjs/toolkit';
import counterSlice from '../features/counter/counterSlice';
import todosSlice from '../features/todos/todosSlice';

export const rootReducer = combineReducers({
  counter: counterSlice.reducer,
  todos: todosSlice.reducer
});

Environment-Specific Configuration

const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      // Disable dev middleware in production
      immutableCheck: __DEV__,
      serializableCheck: __DEV__,
      thunk: {
        extraArgument: { api, logger }
      }
    }),
  devTools: __DEV__ && {
    actionSanitizer: (action) => ({
      ...action,
      // Remove sensitive data from DevTools
      payload: action.type.includes('auth') ? '***' : action.payload
    })
  }
});

Install with Tessl CLI

npx tessl i tessl/npm-reduxjs--toolkit

docs

actions-reducers.md

async-thunks.md

core-store.md

entity-adapters.md

index.md

middleware.md

react-integration.md

rtk-query-react.md

rtk-query.md

utilities.md

tile.json