"composeEnhancers" is not a function in ReactJS
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:
- elvis operator checks if
window?.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
is defined - if it not exist it evaluates to
undefined
so first part of code returns false (if we are in development mode -> true && undefined = false) and fallback evaluates