I am a complete beginner, I'm following a tutorial on redux thunk and keep getting this error:
redux.js:642 Uncaught TypeError: middleware is not a function
at redux.js:642:1
at Array.map (<anonymous>)
at redux.js:641:1
at HTMLDocument.main (bootstrap.js:21:22)
This is the line:
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
And this is my code:
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import reducers from "./reducers";
import thunk from 'redux-thunk';
const createStoreWithMiddleware = applyMiddleware(thunk)(createStore);
import "./style/main.scss";
import Home from "./components/home";
import Results from "./components/results";
function main() {
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<BrowserRouter>
<Switch>
<Route path='/' exact component={Home}/>
<Route path='/results' component={Results}/>
</Switch>
</BrowserRouter>
</Provider>,
document.querySelector(".app-wrapper")
);
}
document.addEventListener("DOMContentLoaded", main);
The only thing I can add is that it works for my tutot but the tutorial is fairly old. In my code the "createStore" and "ReactDOM.render(" are crossed out.
We have been explained practically nothing (don't tell me to leave the course 'cause I can't), been reading what each thing is on my own and still don't undestand much. It's my first approach.
I have read other questions and have changede the import to:
import {thunk} from 'redux-thunk';
I've also tried:
const store = createStore(
reducers,
applyMiddleware(thunk)
);
npm install redux redux-thunk react-redux
I also didn't know if I need to change anything else appart from that.
The error you have typically manifests when importing Thunk incorrectly. thunk
is a named export in the current version, so import { thunk } from 'redux-thunk';
is correct. You can check my answer here for more details.
That said, your Redux store setup/usage is highly irregular. Normally you pass applyMiddleware(thunk)
to the deprecated/legacy createStore
function, along with the reducers, etc. You also appear to create a new store each time main
renders because you are creating it inline in the props. You should create the Redux store outside the React tree so it's provided to the app as a stable reference. If the reactDOM.render
is also crossed out it likely means you are using React 18 which changed how the app is mounted a bit.
Example:
import React from "react";
import { createRoot } from "react-dom/client";
import { Provider } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import { thunk } from 'redux-thunk';
import { BrowserRouter, Switch, Route } from "react-router-dom";
import reducers from "./reducers";
import "./style/main.scss";
import Home from "./components/home";
import Results from "./components/results";
const store = createStore(
reducers,
applyMiddleware(thunk),
);
function main() {
const rootElement = document.getElementById("app-wrapper");
const root = createRoot(rootElement);
root.render(
<Provider store={store}>
<BrowserRouter>
<Switch>
<Route path='/results' component={Results} />
<Route path='/' component={Home} />
</Switch>
</BrowserRouter>
</Provider>
);
}
That said, the Redux code you are trying to use is considered outdated. Current Redux is written using Redux-Toolkit (RTK) which streamlines the store creation and greatly reduces the amount of boilerplate you need to write. RTK also has the benefit of including the Thunk middleware enabled right out-of-the-box. An example update might look like the following:
import React from "react";
import { createRoot } from "react-dom/client";
import { Provider } from "react-redux";
import { configureStore } from "@reduxjs/toolkit";
import { BrowserRouter, Switch, Route } from "react-router-dom";
import rootReducer from "./reducers";
import "./style/main.scss";
import Home from "./components/home";
import Results from "./components/results";
const store = configureStore({
reducer: rootReducer,
});
function main() {
const rootElement = document.getElementById("app-wrapper");
const root = createRoot(rootElement);
root.render(
<Provider store={store}>
<BrowserRouter>
<Switch>
<Route path='/results' component={Results} />
<Route path='/' component={Home} />
</Switch>
</BrowserRouter>
</Provider>
);
}