Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"composeEnhancers" is not a function in ReactJS

Tags:

node.js

npm

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
like image 407
Kevdog777 Avatar asked Aug 23 '19 14:08

Kevdog777


2 Answers

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;
like image 67
danisan00 Avatar answered Nov 13 '22 07:11

danisan00


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
like image 20
olejniczag Avatar answered Nov 13 '22 06:11

olejniczag