I am getting the below error in my code:
TypeError: composeEnhancers is not a function
const store = createStore(rootReducer, composeEnhancers(
applyMiddleware(thunk)
));
Can anyone see where the issue lies here? I don't understand as I have just copied my ReactJS instructor's code and he doesn't get this error, yet I do.
My whole code is shown here:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import burgerBuilderReducer from './store/reducers/burgerBuilder';
import orderReducer from './store/reducers/order';
import authReducer from './store/reducers/auth';
const composeEnhancers = process.env.NODE_ENV === 'development' ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : null || compose;
const rootReducer = combineReducers({
burgerBuilder: burgerBuilderReducer,
order: orderReducer,
auth: authReducer
});
const store = createStore(rootReducer, composeEnhancers(
applyMiddleware(thunk)
));
const app = (
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
</Provider>
);
ReactDOM.render( app, document.getElementById( 'root' ) );
registerServiceWorker();
A more descriptive error (in the browser's console) shows:
Uncaught TypeError: composeEnhancers is not a function
at Object../src/index.js (index.js:23)
at __webpack_require__ (bootstrap 2dae6e05073e9d71bfd6:698)
at fn (bootstrap 2dae6e05073e9d71bfd6:111)
at Object.0 (order.js:59)
at __webpack_require__ (bootstrap 2dae6e05073e9d71bfd6:698)
at bootstrap 2dae6e05073e9d71bfd6:796
at bootstrap 2dae6e05073e9d71bfd6:796
You are likely running your app in dev mode in a browser that doesn't have Redux DevTools installed.
The problem is in this line:
const composeEnhancers = process.env.NODE_ENV === 'development' ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : null || compose;
Due to operator precedence rules, this is equivalent to:
const composeEnhancers = process.env.NODE_ENV === 'development' ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : (null || compose);
Or if you prefer:
let composeEnhancers = null;
if (process.env.NODE_ENV === 'development') {
composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__;
} else {
composeEnhancers = compose;
}
So, if you are in dev mode and you don't have Redux DevTools extension installed in your browser, your app will break, because window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
is not defined.
What you really need is this:
let composeEnhancers = null;
if (process.env.NODE_ENV === 'development') {
composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
} else {
composeEnhancers = compose;
}
Or, more simply:
const composeEnhancers = (process.env.NODE_ENV === 'development' ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : null) || compose;
2020 update
With Elvis (or safe navigation) operator that was introduced in TypeScript 3.8 it's possible to simplify it and make it look much better. Like below:
const composeEnhancers =
(process.env.NODE_ENV === 'development' &&
(window as any)?.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
compose;
What it means is:
window?.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
is definedundefined
so first part of code returns false (if we are in development mode -> true && undefined = false) and fallback evaluatesIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With