redux-thunk: middleware is not a function

I can’t tell if this is a redux-thunk or a redux issue.

I have a store like this:

const store = compose(
    applyMiddleware(
        thunk,
        logger
    )
)(createStore)(counter);

This results in an error message:

./node_modules/redux/lib/utils/applyMiddleware.js:50
        return middleware(middlewareAPI);
               ^

TypeError: middleware is not a function
    at ./node_modules/redux/lib/utils/applyMiddleware.js:50:16
    at Array.map (native)
    at ./node_modules/redux/lib/utils/applyMiddleware.js:49:27
    at Object.<anonymous> (./index.js:63:105)
    at Module._compile (module.js:425:26)
    at Object.Module._extensions..js (module.js:432:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:311:12)
    at Function.Module.runMain (module.js:457:10)
    at startup (node.js:136:18)

If I comment out thunk above, it continues:

const store = compose(
    applyMiddleware(
        // thunk,
        logger
    )
)(createStore)(counter);

store.dispatch({ type: INCREMENT });
store.dispatch({ type: INCREMENT });
store.dispatch({ type: DECREMENT });
$ node --harmony_default_parameters --harmony_destructuring index.js
will dispatch { type: 'INCREMENT' }
state after dispatch 1
will dispatch { type: 'INCREMENT' }
state after dispatch 2
will dispatch { type: 'DECREMENT' }
state after dispatch 1

About this issue

  • Original URL
  • State: closed
  • Created 9 years ago
  • Comments: 34

Commits related to this issue

Most upvoted comments

use “import thunk from “redux-thunk”;” not “import {thunk} from “redux-thunk”;”

After facing recently same issue and none of the above worked for me I’ve tried with importing just {createLogger} that sorted the issue when new logger instance was passed to applyMiddleware.

import { applyMiddleware, createStore } from 'redux';
import promise from "redux-promise-middleware";
import thunk from "redux-thunk"
import { createLogger } from "redux-logger";

import reducer from "./reducers";
const middleware = applyMiddleware(  promise(),  thunk,  createLogger() );
export default createStore(reducer, middleware);

Works under Typescript and Babel because in my attempts to isolate the route cause I’ve switched to each of them. The issue is observed with latest redux packages at the time of my writing and solution is tested only against them

"react-redux": "^5.0.5",
"redux": "^3.7.1",
"redux-logger": "^3.0.6",
"redux-promise-middleware": "^4.3.0",
"redux-thunk": "^2.2.0"

@born2net

I don’t understand what you’re trying to do. You can either

import thunk from 'redux-thunk'

in an ES modules environment, or

var thunk = require('redux-thunk').default

in a CommonJS environment.

Why aren’t these cases working for you?

ah ha - https://github.com/Microsoft/TypeScript/issues/2242#issuecomment-92218146. Note: if you’re using typescript instead of babel as your transpiler, you have to use import thunkMiddleware = require("redux-thunk"); to get the default module.

Redux Thunk currently uses CommonJS. It does not explicitly export a “default”. We should probably start using ES modules internally and export a CommonJS compat build with default as the exported key, as well as an ES modules build, but this can only be done after bumping a version because it breaks backwards compat.

It’s provably too late but with typescript tsc and the dt~redux-thunk typings I could fix it by doing: import { default as thunk } from "redux-thunk"; and then createStore(reducer, applyMiddleware(thunk));

Here another permutation for anyone using commonjs modules with Typescript. Works for me… YMMV.

typings install redux-thunk --save

Then:

import * as thunk from 'redux-thunk';

redux.createStore(rootReducer, applyMiddleware(
  thunk.default   // <-- the aforementioned `.default`
));

I’ve followed this thread but I can’t seem to resolve my issue.

I’m getting the middleware is not a function console error after upgrading to Babel 6. My original code used the ES6 import

import thunk from 'redux-thunk'

And I’ve tried the ES5 + default

const thunk = require('redux-thunk').default;

I was on redux-thunk v1 but have upgraded to v2.1.0 and redux v3.5.2.

I’m stumped…

EDIT:

Facepalm. It wasn’t thunk afterall, but logger where I am using ES5 require.

const logger = require('../middleware/logger')

becomes

const logger = require('../middleware/logger').default;

Hope this helps someone else. 👍

Thank you oupsss …

@mattdell facepalm +1, thanks for the .default hint 😃

I just looked at the PR and it was already in this format. While my typescript compiler 1.7.6 seems to accept either version, web storm 11 complains that thunk is not exported default. And my understanding was that you couldn’t use the import default syntax without declaring an default export. Here is the info from the TypeScript specification. So I do not understand why it was changed. The only thing i can tell from this an the other issue is that web pack couldn’t properly load the file based on the import statement which sounds like a webpack issue. Could someone either correct my understanding of the TypeScript spec or reopen this issue?

image

image

image