{"id":17052,"library":"redux-thunk","title":"Redux Thunk Middleware","description":"Redux Thunk is a middleware for Redux that enables writing action creators that return functions (thunks) instead of plain action objects. These thunk functions receive the `dispatch` and `getState` methods of the Redux store, allowing for asynchronous logic, conditional dispatching, and interaction with the store's current state. The current stable version is 3.1.0, released in conjunction with major updates to the entire Redux ecosystem, including Redux Toolkit 2.0, Redux core 5.0, and React-Redux 9.0. Its release cadence is closely tied to the broader Redux project releases. A key differentiator is its simplicity and official endorsement as the standard approach for handling async logic in Redux, often being included by default in `configureStore` from Redux Toolkit. It also supports injecting custom arguments, facilitating dependency injection patterns for services or APIs.","status":"active","version":"3.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/reduxjs/redux-thunk","tags":["javascript","redux","thunk","middleware","redux-middleware","flux","typescript"],"install":[{"cmd":"npm install redux-thunk","lang":"bash","label":"npm"},{"cmd":"yarn add redux-thunk","lang":"bash","label":"yarn"},{"cmd":"pnpm add redux-thunk","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Redux Thunk is middleware for Redux and requires a compatible version of Redux to function. Version 3.x specifically targets Redux v5.0.0 and above.","package":"redux","optional":false}],"imports":[{"note":"Since v3.0.0, redux-thunk uses named exports. Previous versions (v2.x) used a default export.","wrong":"import thunk from 'redux-thunk';","symbol":"thunk","correct":"import { thunk } from 'redux-thunk';"},{"note":"For CommonJS environments in v3.x, use named destructuring. For v2.x, `require('redux-thunk').default` was necessary after v2.0.0.","wrong":"const thunk = require('redux-thunk');","symbol":"thunk (CommonJS)","correct":"const { thunk } = require('redux-thunk');"},{"note":"Represents the type of a thunk action, useful for defining thunk functions with proper TypeScript inference.","symbol":"ThunkAction","correct":"import type { ThunkAction } from 'redux-thunk';"},{"note":"Represents the type of the Redux dispatch function when thunk middleware is applied, allowing dispatching of thunks as well as plain actions.","symbol":"ThunkDispatch","correct":"import type { ThunkDispatch } from 'redux-thunk';"}],"quickstart":{"code":"import { createStore, applyMiddleware, AnyAction } from 'redux';\nimport { thunk, ThunkAction, ThunkDispatch } from 'redux-thunk';\n\ninterface RootState {\n  count: number;\n}\n\nconst initialState: RootState = { count: 0 };\n\nfunction rootReducer(state: RootState = initialState, action: AnyAction): RootState {\n  switch (action.type) {\n    case 'INCREMENT':\n      return { ...state, count: state.count + 1 };\n    case 'DECREMENT':\n      return { ...state, count: state.count - 1 };\n    default:\n      return state;\n  }\n}\n\n// Apply the thunk middleware\nconst store = createStore(rootReducer, applyMiddleware(thunk));\n\n// Define a simple asynchronous thunk action\nconst incrementAsync = (amount: number): ThunkAction<void, RootState, unknown, AnyAction> =>\n  (dispatch: ThunkDispatch<RootState, unknown, AnyAction>, getState) => {\n    console.log(`Current count before async: ${getState().count}`);\n    setTimeout(() => {\n      dispatch({ type: 'INCREMENT', payload: amount });\n      console.log(`Current count after async: ${getState().count}`);\n    }, 1000);\n  };\n\nconsole.log('Initial state:', store.getState());\n\n(store.dispatch as ThunkDispatch<RootState, unknown, AnyAction>)(incrementAsync(1));\n\nconsole.log('State after dispatching async thunk (will update later):', store.getState());","lang":"typescript","description":"This quickstart demonstrates the manual setup of Redux Thunk with `createStore` and `applyMiddleware` in TypeScript, including a basic asynchronous thunk action."},"warnings":[{"fix":"Update your imports to use named exports: `import { thunk } from 'redux-thunk';` or `const { thunk } = require('redux-thunk');`.","message":"Redux Thunk v3.0.0 and newer versions changed from a default export to a named export. Imports using `import thunk from 'redux-thunk'` or `const thunk = require('redux-thunk').default` will fail.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Ensure your build tools (Webpack, Rollup, etc.) are configured for modern module resolution. For Node.js, ensure correct `package.json` `type` field usage or use appropriate import/require syntax.","message":"Redux Thunk v3.0.0 introduced significant changes to its packaging for improved ESM/CJS compatibility, aligning with Node.js's `type: \"module\"` approach. This may affect build tools or environments with strict module resolution.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Upgrade your `redux` package to `^5.0.0` or higher. If you cannot upgrade Redux, you may need to stick with `redux-thunk` v2.x.","message":"Redux Thunk v3.x has a peer dependency on Redux v5.0.0 or higher. Using it with older Redux versions (e.g., v4.x) might lead to runtime issues or TypeScript incompatibilities.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"For v2.x, use `require('redux-thunk').default`. For v3.x, switch to `const { thunk } = require('redux-thunk');`.","message":"In Redux Thunk v2.0.0, the CommonJS `require('redux-thunk')` without `.default` was deprecated, and required `require('redux-thunk').default` to get the middleware. This pattern is entirely obsolete in v3.x due to the named export change.","severity":"deprecated","affected_versions":">=2.0.0 <3.0.0"},{"fix":"When using Redux Toolkit, avoid manually adding `thunk` middleware. If you need to customize `thunk` (e.g., with `extraArgument`), use the `getDefaultMiddleware` callback within `configureStore`'s `middleware` option.","message":"If you are using Redux Toolkit, `redux-thunk` is already included by default in `configureStore`. Manually applying it via `applyMiddleware` with `configureStore` can lead to duplicate middleware or unexpected behavior.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-22T00:00:00.000Z","next_check":"2026-07-21T00:00:00.000Z","problems":[{"fix":"Change your import statement to `import { thunk } from 'redux-thunk';`.","cause":"Attempting to import `redux-thunk` as a default export in v3.x (e.g., `import thunk from 'redux-thunk';`) when it now uses named exports.","error":"TypeError: (0 , redux_thunk__WEBPACK_IMPORTED_MODULE_0__.default) is not a function"},{"fix":"For v3.x, use `const { thunk } = require('redux-thunk');`. For v2.x, ensure you are using `const thunk = require('redux-thunk').default;`.","cause":"This error can occur in CommonJS environments or with incorrect tooling if you are trying to use `require('redux-thunk')` directly with `applyMiddleware(thunk)` in v3.x.","error":"TypeError: thunk is not a function"},{"fix":"Cast your `store.dispatch` to `ThunkDispatch` or ensure your `dispatch` parameter in hooks is correctly typed (e.g., `const dispatch = useDispatch<AppDispatch>();` where `AppDispatch` includes `ThunkDispatch`).","cause":"This TypeScript error typically arises when attempting to `dispatch` a thunk action without correctly typing your `dispatch` function to accept `ThunkAction` types.","error":"TS2345: Argument of type 'ThunkAction<void, any, unknown, AnyAction>' is not assignable to parameter of type 'AnyAction'."},{"fix":"Configure the `thunk` middleware with `extraArgument` via `applyMiddleware(thunk.withExtraArgument(myApi))` for manual setup, or within `configureStore`'s `middleware` option: `thunk: { extraArgument: myApi }`.","cause":"This happens when a thunk function expects an `extraArgument` (e.g., `api`) but `redux-thunk` was not configured with one, or the `extraArgument` was not provided as an object when multiple values are expected.","error":"TypeError: Cannot read properties of undefined (reading 'api')"}],"ecosystem":"npm","meta_description":null}