Error with Redux DevTools Extension using TS: "Property '__REDUX_DEVTOOLS_EXTENSION_COMPOSE__' does not exist on type 'Window'."?

ReactjsTypescriptReduxReact ReduxRedux Devtools-Extension

Reactjs Problem Overview


I'm getting this error on my index.tsx.

Property 'REDUX_DEVTOOLS_EXTENSION_COMPOSE' does not exist on type 'Window'.

Here is my index.tsx code:

import * as React from 'react';
import * as ReactDOM from 'react-dom';
import App from './App';
import './index.css';
import registerServiceWorker from './registerServiceWorker';

import { Provider } from 'react-redux';

import { createStore, compose, applyMiddleware } from 'redux';
import rootReducer from './store/reducers';

import thunk from 'redux-thunk';

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

 const store = createStore(rootReducer, composeEnhancers(
     applyMiddleware(thunk)
 ));

ReactDOM.render(  <Provider store={store}><App /></Provider>, document.getElementById('root'));

registerServiceWorker();

I've installed @types/npm install --save-dev redux-devtools-extension and I'm using create-react-app-typescript. Thanks alot for any tips for what's going on in advance.

Reactjs Solutions


Solution 1 - Reactjs

This is a special case of this question. Redux doesn't provide types for __REDUX_DEVTOOLS_EXTENSION_COMPOSE__ because this function is exposed by Redux DevTools, not Redux itself.

It's either:

const composeEnhancers = window['__REDUX_DEVTOOLS_EXTENSION_COMPOSE__'] as typeof compose || compose;

Or:

declare global {
    interface Window {
      __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof compose;
    }
}

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

This is already done by redux-devtools-extension package that contains TypeScript typings. If it's installed, its imports should be used instead of accessing __REDUX_DEVTOOLS_EXTENSION_COMPOSE__ manually.

Solution 2 - Reactjs

The most streamlined way to make this work with TypeScript is to use the redux-devtools-extension and install as a dev dependency as follows:

npm install --save-dev redux-devtools-extension

The next step for those new to redux and these developer tools was confusing and unclear. The docs all have code like the following:

const store = createStore(reducer, composeWithDevTools(
  applyMiddleware(...middleware),
  // other store enhancers if any
));

The problem is I don't have any middleware configured so this wasn't working. In it's most primitive usage, this is all you need:

import { composeWithDevTools } from 'redux-devtools-extension';

const store = createStore(myReducer, composeWithDevTools());

At this point if you click the extension in the browser and there is a valid redux store, you will be able to inspect the state.

This is an alternative approach to using (window as any) and also clears up just exaclty how to use the redux-devtools-extension in its minimal form.

Solution 3 - Reactjs

My approach to the issue was the following:

export const composeEnhancers =
  (window && (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose;

Solution 4 - Reactjs

This is how you can use redux-dev-tools in a typescript react application.

Create global Interface for the Window object:
declare global {
  interface Window {
    __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof compose;
  }
}
Then, create composeEnhancers as follows:
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
Then create a store.
const store = createStore(rootReducers, composeEnhancers());

rootReducers - in my case refers to combinedReducers created in a surparate file.

Now you can use Provider as usual in React.js as:

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);
All the code in the index.tsx
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import rootReducers from "./reducers";

import { Provider } from "react-redux";
import { createStore, compose, applyMiddleware } from "redux";

declare global {
  interface Window {
    __REDUX_DEVTOOLS_EXTENSION_COMPOSE__?: typeof compose;
  }
}

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(rootReducers, composeEnhancers());

ReactDOM.render(
  <React.StrictMode>
    <Provider store={store}>
      <App />
    </Provider>
  </React.StrictMode>,
  document.getElementById("root")
);
reportWebVitals();

Solution 5 - Reactjs

Working as a charm:

const store = createStore(
	rootReducer,
	initialState,
	compose(
		applyMiddleware(...middleware),
		(window as any).__REDUX_DEVTOOLS_EXTENSION__ && (window as any).__REDUX_DEVTOOLS_EXTENSION__()
	)		
	
);

Solution 6 - Reactjs

I had the same issue too however, I'm also using redux-thunk as a middleware. Running

npm install --save-dev redux-devtools-extension

and then adding in

import { composeWithDevTools } from 'redux-devtools-extension'

to index.tsx did the trick for me, as well as updating the store to

const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)))

My full index.tsx is below. Hopefully this will help anyone with the same issue that is using middleware such as redux-thunk

import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './containers/App/App'
import { BrowserRouter } from 'react-router-dom'
import { Provider } from 'react-redux'
import { createStore, applyMiddleware, combineReducers } from 'redux'
import thunk from 'redux-thunk'
import authReducer from './store/reducers/auth'
import * as serviceWorker from './serviceWorker'
import { composeWithDevTools } from 'redux-devtools-extension'


const rootReducer = combineReducers({
  auth: authReducer
})
const store = createStore(rootReducer, composeWithDevTools(applyMiddleware(thunk)))

const app = (
  <Provider store={store}>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </Provider>
)

ReactDOM.render(app, document.getElementById('root'))

serviceWorker.unregister()

Solution 7 - Reactjs

if any one still stuck into this issue I fixed it and this is my final store.js file with following packages 1- Redux Thunk 2- Connected React Router 3- History

import { createStore, applyMiddleware, compose } from 'redux';
import { routerMiddleware } from 'connected-react-router';
import thunk from 'redux-thunk';
import {createBrowserHistory} from 'history';
import rootReducer from '../redux/reducers';
export const history = createBrowserHistory();
const initialState = {}
const enhancers = []
const middleware = [
    thunk,
    routerMiddleware(history)
]

if (process.env.NODE_ENV === 'development') {
    const devToolsExtension = (window as any).__REDUX_DEVTOOLS_EXTENSION__ && (window as any).__REDUX_DEVTOOLS_EXTENSION__() || compose;
    if (typeof devToolsExtension === 'function') {
        enhancers.push(devToolsExtension)
    }
}

const composedEnhancers = compose(
    applyMiddleware(...middleware),
    ...enhancers
);

export default createStore(
    rootReducer,
    initialState,
    composedEnhancers
);

Solution 8 - Reactjs

Had same issue changed I just changed

window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()

to

window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__() || compose

to get past an undefined apply issue when using createStore(reducer, initial state, compose(applyMiddleware

Solution 9 - Reactjs

For anyone struggling with getting concurrently to work, the general advice I found is to replace your "client" script in package.json with: "client": "cd client && npm start",

I tried this and I still got an error, so then I tried: "client": "cd client && cd my-app && npm start",

This worked for me! The problem is that when you use create-react-app inside the "client" folder, there is an added level in between the client folder and your public and src folders which is called "my-app" by default. Using Brad's code, npm misses this folder so can't find the react files it needs to start your app.

Solution 10 - Reactjs

In my case I have used react-redux-devtools. Try this solution may be it will help you to resolve your issue.

import { applyMiddleware, createStore } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import createSagaMiddleware from "redux-saga";
import { rootReducer } from "../reducers";
import { AppState } from "@eneto/api-client";

import { initUserState } from "../../modules/users/user-reducer";
import { initUsersState } from "../../modules/users/users-reducer";
import { initListsState } from "../../modules/lists/lists-reducer";
import { initListState } from "../../modules/lists/list-reducer";

// initialValues
const init: AppState = {
    currentUser: initUserState,
    users: initUsersState,
    lists: initListsState,
    currentList: initListState
};

export function store(initialState: AppState = init) {
    const sagaMiddleware = createSagaMiddleware();
    const middleware = [sagaMiddleware];

    return {
        ...createStore(rootReducer, initialState, composeWithDevTools(applyMiddleware(...middleware))),
        runSaga: sagaMiddleware.run
    };
}

#reactjs

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjustkeithcarrView Question on Stackoverflow
Solution 1 - ReactjsEstus FlaskView Answer on Stackoverflow
Solution 2 - ReactjsatconwayView Answer on Stackoverflow
Solution 3 - ReactjsAustris CirulnieksView Answer on Stackoverflow
Solution 4 - ReactjscrispengariView Answer on Stackoverflow
Solution 5 - ReactjsArturasView Answer on Stackoverflow
Solution 6 - ReactjsNick TheoView Answer on Stackoverflow
Solution 7 - ReactjsDanialView Answer on Stackoverflow
Solution 8 - Reactjsmmunier44View Answer on Stackoverflow
Solution 9 - ReactjsGhausc1View Answer on Stackoverflow
Solution 10 - ReactjsOtabek ButcherView Answer on Stackoverflow