可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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.
回答1:
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.
回答2:
My approach to the issue was the following:
export const composeEnhancers =
(window && (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose;
回答3:
Working as a charm:
const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(...middleware),
(window as any).__REDUX_DEVTOOLS_EXTENSION__ && (window as any).__REDUX_DEVTOOLS_EXTENSION__()
)
);
回答4:
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.
回答5:
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
);
回答6:
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
回答7:
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.