or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

actions-reducers.mdasync-thunks.mdcore-store.mdentity-adapters.mdindex.mdmiddleware.mdreact-integration.mdrtk-query-react.mdrtk-query.mdutilities.md

core-store.mddocs/

0

# Store Configuration

1

2

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

3

4

## Capabilities

5

6

### Configure Store

7

8

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

9

10

```typescript { .api }

11

/**

12

* A friendly abstraction over Redux's createStore() with good defaults

13

* @param options - Configuration options for the store

14

* @returns Enhanced Redux store with thunk support and additional methods

15

*/

16

function configureStore<

17

S = any,

18

A extends Action = AnyAction,

19

M extends Middlewares<S> = Middlewares<S>,

20

E extends Enhancers = Enhancers

21

>(options: ConfigureStoreOptions<S, A, M, E>): EnhancedStore<S, A, E>;

22

23

interface ConfigureStoreOptions<S, A extends Action, M extends Middlewares<S>, E extends Enhancers, P = S> {

24

/** Root reducer or reducer map object */

25

reducer: Reducer<S, A> | ReducersMapObject<S, A>;

26

/** Callback to customize middleware array (receives getDefaultMiddleware) */

27

middleware?: ((getDefaultMiddleware: GetDefaultMiddleware<S>) => M) | M;

28

/** Enable Redux DevTools (default: true in development) */

29

devTools?: boolean | DevToolsOptions;

30

/** Initial state value */

31

preloadedState?: P;

32

/** Callback to customize store enhancers */

33

enhancers?: ((getDefaultEnhancers: GetDefaultEnhancers<S>) => E) | E;

34

}

35

36

interface EnhancedStore<S = any, A extends Action = AnyAction, E = any> extends Store<S, A> {

37

/** Dispatch function with thunk support */

38

dispatch: Dispatch<A> & ThunkDispatch<S, any, A>;

39

}

40

```

41

42

**Usage Examples:**

43

44

```typescript

45

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

46

import counterSlice from './features/counter/counterSlice';

47

import todosSlice from './features/todos/todosSlice';

48

49

// Basic store setup

50

const store = configureStore({

51

reducer: {

52

counter: counterSlice.reducer,

53

todos: todosSlice.reducer

54

}

55

});

56

57

// Custom middleware configuration

58

const store = configureStore({

59

reducer: rootReducer,

60

middleware: (getDefaultMiddleware) =>

61

getDefaultMiddleware({

62

serializableCheck: {

63

ignoredActions: ['persist/PERSIST']

64

}

65

}).concat(logger),

66

devTools: process.env.NODE_ENV !== 'production'

67

});

68

69

// With preloaded state

70

const store = configureStore({

71

reducer: rootReducer,

72

preloadedState: {

73

counter: { value: 5 },

74

todos: []

75

}

76

});

77

78

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

79

export type AppDispatch = typeof store.dispatch;

80

export default store;

81

```

82

83

### Default Middleware

84

85

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

86

87

```typescript { .api }

88

/**

89

* Returns the default middleware array used by configureStore

90

* @param options - Options to customize the default middleware

91

* @returns Array of middleware functions

92

*/

93

interface GetDefaultMiddleware<S> {

94

<O extends MiddlewareOptions<S>>(options?: O): Tuple<DefaultMiddlewareArray<S, O>>;

95

}

96

97

interface MiddlewareOptions<S> {

98

/** Enable thunk middleware (default: true) */

99

thunk?: boolean | ThunkOptions<S>;

100

/** Enable immutable state invariant middleware (default: true in development) */

101

immutableCheck?: boolean | ImmutableStateInvariantMiddlewareOptions;

102

/** Enable serializable state invariant middleware (default: true in development) */

103

serializableCheck?: boolean | SerializableStateInvariantMiddlewareOptions;

104

/** Enable action creator invariant middleware (default: true in development) */

105

actionCreatorCheck?: boolean | ActionCreatorInvariantMiddlewareOptions;

106

}

107

108

type DefaultMiddlewareArray<S, O extends MiddlewareOptions<S>> = [

109

ThunkMiddleware<S>,

110

...ConditionalMiddleware<O['immutableCheck'], ImmutableStateInvariantMiddleware<S>>,

111

...ConditionalMiddleware<O['serializableCheck'], SerializableStateInvariantMiddleware>,

112

...ConditionalMiddleware<O['actionCreatorCheck'], ActionCreatorInvariantMiddleware>

113

];

114

```

115

116

**Usage Examples:**

117

118

```typescript

119

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

120

import logger from 'redux-logger';

121

122

// Add custom middleware to defaults

123

const store = configureStore({

124

reducer: rootReducer,

125

middleware: (getDefaultMiddleware) =>

126

getDefaultMiddleware()

127

.prepend(

128

// Correctly typed middleware can be added before

129

rateLimitMiddleware({ requests: 5, window: 1000 })

130

)

131

.concat(

132

// And after the defaults

133

logger

134

)

135

});

136

137

// Customize default middleware options

138

const store = configureStore({

139

reducer: rootReducer,

140

middleware: (getDefaultMiddleware) =>

141

getDefaultMiddleware({

142

thunk: {

143

extraArgument: { api, analytics }

144

},

145

serializableCheck: {

146

ignoredActions: ['persist/PERSIST', 'persist/REHYDRATE']

147

}

148

})

149

});

150

151

// Disable development middleware in production

152

const store = configureStore({

153

reducer: rootReducer,

154

middleware: (getDefaultMiddleware) =>

155

getDefaultMiddleware({

156

immutableCheck: process.env.NODE_ENV !== 'production',

157

serializableCheck: process.env.NODE_ENV !== 'production'

158

})

159

});

160

```

161

162

### Store Enhancers

163

164

Configure store enhancers for additional functionality like persistence or analytics.

165

166

```typescript { .api }

167

/**

168

* Get default store enhancers (auto-batching by default)

169

* @param options - Options to customize enhancers

170

* @returns Array of store enhancers

171

*/

172

interface GetDefaultEnhancers<S> {

173

<O extends EnhancerOptions>(options?: O): Tuple<DefaultEnhancerArray<S, O>>;

174

}

175

176

interface EnhancerOptions {

177

/** Enable auto-batching enhancer (default: true) */

178

autoBatch?: boolean | AutoBatchOptions;

179

}

180

181

type DefaultEnhancerArray<S, O extends EnhancerOptions> = [

182

...ConditionalEnhancer<O['autoBatch'], AutoBatchEnhancer>

183

];

184

185

/** Store enhancer for automatic action batching */

186

function autoBatchEnhancer(options?: AutoBatchOptions): StoreEnhancer;

187

188

interface AutoBatchOptions {

189

/** Custom batch type checker */

190

type?: 'tick' | 'timer' | 'callback' | ((action: Action) => boolean);

191

}

192

```

193

194

**Usage Examples:**

195

196

```typescript

197

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

198

import { persistStore, persistReducer } from 'redux-persist';

199

200

// Add persistence enhancer

201

const persistConfig = {

202

key: 'root',

203

storage,

204

};

205

206

const persistedReducer = persistReducer(persistConfig, rootReducer);

207

208

const store = configureStore({

209

reducer: persistedReducer,

210

enhancers: (getDefaultEnhancers) =>

211

getDefaultEnhancers().concat(

212

// Add your custom enhancers here

213

)

214

});

215

216

// Custom auto-batching configuration

217

const store = configureStore({

218

reducer: rootReducer,

219

enhancers: (getDefaultEnhancers) =>

220

getDefaultEnhancers({

221

autoBatch: { type: 'tick' }

222

})

223

});

224

```

225

226

### Development Middleware

227

228

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

229

230

```typescript { .api }

231

/**

232

* Middleware that detects mutations to state

233

* @param options - Configuration options

234

* @returns Middleware function

235

*/

236

function createImmutableStateInvariantMiddleware<S = any>(

237

options?: ImmutableStateInvariantMiddlewareOptions

238

): Middleware<{}, S>;

239

240

interface ImmutableStateInvariantMiddlewareOptions {

241

/** Enable the middleware */

242

isImmutable?: (value: any) => boolean;

243

/** Paths to ignore when checking for mutations */

244

ignoredPaths?: string[];

245

/** Function to determine if checking should be ignored */

246

warnAfter?: number;

247

}

248

249

/**

250

* Middleware that detects non-serializable values in state and actions

251

* @param options - Configuration options

252

* @returns Middleware function

253

*/

254

function createSerializableStateInvariantMiddleware(

255

options?: SerializableStateInvariantMiddlewareOptions

256

): Middleware<{}, any>;

257

258

interface SerializableStateInvariantMiddlewareOptions {

259

/** Actions to ignore when checking */

260

ignoredActions?: string[];

261

/** Action paths to ignore */

262

ignoredActionPaths?: string[];

263

/** State paths to ignore */

264

ignoredPaths?: string[];

265

/** Function to determine if value is serializable */

266

isSerializable?: (value: any) => boolean;

267

/** Function to get entries from value for checking */

268

getEntries?: (value: any) => [string, any][];

269

/** Execution time warning threshold */

270

warnAfter?: number;

271

}

272

273

/**

274

* Middleware that validates action creators are not called incorrectly

275

* @param options - Configuration options

276

* @returns Middleware function

277

*/

278

function createActionCreatorInvariantMiddleware(

279

options?: ActionCreatorInvariantMiddlewareOptions

280

): Middleware;

281

282

interface ActionCreatorInvariantMiddlewareOptions {

283

/** Enable the middleware */

284

isActionCreator?: (action: any) => boolean;

285

}

286

```

287

288

**Usage Examples:**

289

290

```typescript

291

import {

292

configureStore,

293

createImmutableStateInvariantMiddleware,

294

createSerializableStateInvariantMiddleware

295

} from '@reduxjs/toolkit';

296

297

const store = configureStore({

298

reducer: rootReducer,

299

middleware: (getDefaultMiddleware) =>

300

getDefaultMiddleware({

301

// Configure immutable check

302

immutableCheck: {

303

ignoredPaths: ['items.dates'],

304

warnAfter: 128

305

},

306

// Configure serializable check

307

serializableCheck: {

308

ignoredActions: ['persist/PERSIST', 'persist/REHYDRATE'],

309

ignoredPaths: ['items.map'],

310

warnAfter: 128

311

}

312

})

313

});

314

```

315

316

## Store Types

317

318

### Enhanced Store Interface

319

320

```typescript { .api }

321

/**

322

* Extended Redux store with additional typing for thunk dispatch

323

*/

324

interface EnhancedStore<S = any, A extends Action = AnyAction, E = any> extends Store<S, A> {

325

dispatch: Dispatch<A> & ThunkDispatch<S, any, A>;

326

}

327

328

/**

329

* Configuration options for configureStore

330

*/

331

interface ConfigureStoreOptions<S, A extends Action, M extends Middlewares<S>, E extends Enhancers, P = S> {

332

reducer: Reducer<S, A> | ReducersMapObject<S, A>;

333

middleware?: ((getDefaultMiddleware: GetDefaultMiddleware<S>) => M) | M;

334

devTools?: boolean | DevToolsOptions;

335

preloadedState?: P;

336

enhancers?: ((getDefaultEnhancers: GetDefaultEnhancers<S>) => E) | E;

337

}

338

339

/**

340

* Redux DevTools configuration options

341

*/

342

interface DevToolsOptions {

343

/** Custom action name mapping */

344

actionCreators?: ActionCreatorMapObject;

345

/** Maximum number of actions to keep */

346

maxAge?: number;

347

/** Actions to skip in DevTools */

348

actionSanitizer?: (action: Action, id: number) => Action;

349

/** State sanitizer for DevTools */

350

stateSanitizer?: <S>(state: S, index: number) => S;

351

/** Trace option */

352

trace?: boolean;

353

/** Trace limit */

354

traceLimit?: number;

355

}

356

```

357

358

## Best Practices

359

360

### Store Organization

361

362

```typescript

363

// store/index.ts - Main store configuration

364

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

365

import { rootReducer } from './rootReducer';

366

367

export const store = configureStore({

368

reducer: rootReducer,

369

middleware: (getDefaultMiddleware) =>

370

getDefaultMiddleware({

371

serializableCheck: {

372

ignoredActions: ['persist/PERSIST', 'persist/REHYDRATE']

373

}

374

})

375

});

376

377

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

378

export type AppDispatch = typeof store.dispatch;

379

380

// store/rootReducer.ts - Combined reducers

381

import { combineReducers } from '@reduxjs/toolkit';

382

import counterSlice from '../features/counter/counterSlice';

383

import todosSlice from '../features/todos/todosSlice';

384

385

export const rootReducer = combineReducers({

386

counter: counterSlice.reducer,

387

todos: todosSlice.reducer

388

});

389

```

390

391

### Environment-Specific Configuration

392

393

```typescript

394

const store = configureStore({

395

reducer: rootReducer,

396

middleware: (getDefaultMiddleware) =>

397

getDefaultMiddleware({

398

// Disable dev middleware in production

399

immutableCheck: __DEV__,

400

serializableCheck: __DEV__,

401

thunk: {

402

extraArgument: { api, logger }

403

}

404

}),

405

devTools: __DEV__ && {

406

actionSanitizer: (action) => ({

407

...action,

408

// Remove sensitive data from DevTools

409

payload: action.type.includes('auth') ? '***' : action.payload

410

})

411

}

412

});

413

```