Консоль Redux отображает маршрут и глобальную структуру immutable.iterable error Можете ли вы исправить эту ошибку?
Сведения об ошибке ОбъединитьReducers.js: 29 Предыдущеесостояние, полученное редуктором, имеет неожиданный тип.Ожидаемый аргумент является экземпляром Immutable.Iterable со следующими свойствами: «route», «global», «language».
Приложение JS
Сохранение местоположения и настройки шлюза с сохранением
// Needed for redux-saga es6 generator support
import 'babel-polyfill';
// Import all the third party stuff
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { applyRouterMiddleware, Router, browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import FontFaceObserver from 'fontfaceobserver';
import { useScroll } from 'react-router-scroll';
import 'sanitize.css/sanitize.css';
import 'flexboxgrid/css/flexboxgrid.css';
import injectTapEventPlugin from 'react-tap-event-plugin';
// Import root app
import App from 'containers/App';
// Import selector for `syncHistoryWithStore`
import { makeSelectLocationState } from 'containers/App/selectors';
// Import Language Provider
import LanguageProvider from 'containers/LanguageProvider';
// Load the favicon, the manifest.json file and the .htaccess file
/* eslint-disable import/no-webpack-loader-syntax */
import '!file-loader?name=[name].[ext]!./favicon.ico';
import '!file-loader?name=[name].[ext]!./manifest.json';
import 'file-loader?name=[name].[ext]!./.htaccess'; // eslint-disable-line import/extensions
/* eslint-enable import/no-webpack-loader-syntax */
import configureStore from './store';
// Import i18n messages
import { translationMessages } from './i18n';
// Import CSS reset and Global Styles
import './global-styles';
// Import routes
import createRoutes from './routes';
// Import app saga
import sagas from './containers/App/sagas';
// Observe loading of Open Sans (to remove open sans, remove the <link> tag in
// the index.html file and this observer)
const openSansObserver = new FontFaceObserver('Open Sans', {});
// When Open Sans is loaded, add a font-family using Open Sans to the body
openSansObserver.load().then(
() => {
document.body.classList.add('fontLoaded');
},
() => {
document.body.classList.remove('fontLoaded');
},
);
// Create redux store with history
// this uses the singleton browserHistory provided by react-router
// Optionally, this could be changed to leverage a created history
// e.g. `const browserHistory = useRouterHistory(createBrowserHistory)();`
const initialState = {};
const conf = configureStore(initialState, browserHistory);
const store = conf.store;
const persistor = conf.persistor;
// Sync history and store, as the react-router-redux reducer
// is under the non-default key ("routing"), selectLocationState
// must be provided for resolving how to retrieve the "route" in the state
const history = syncHistoryWithStore(browserHistory, store, {
selectLocationState: makeSelectLocationState(),
});
// Set up the router, wrapping all Routes in the App component
const rootRoute = {
component: App,
childRoutes: createRoutes(store),
};
// Inject default app sagas
sagas.map(store.runSaga);
const render = messages => {
ReactDOM.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<LanguageProvider messages={messages}>
<Router
history={history}
routes={rootRoute}
render={
// Scroll to top when going to a new page, imitating default browser
// behaviour
applyRouterMiddleware(useScroll())
}
/>
</LanguageProvider>
</PersistGate>
</Provider>,
document.getElementById('app'),
);
};
injectTapEventPlugin();
// Hot reloadable translation json files
if (module.hot) {
// modules.hot.accept does not accept dynamic dependencies,
// have to be constants at compile-time
module.hot.accept('./i18n', () => {
render(translationMessages);
});
}
// Chunked polyfill for browsers without Intl support
if (!window.Intl) {
new Promise(resolve => {
resolve(import('intl'));
})
.then(() =>
Promise.all([import('intl/locale-data/jsonp/en.js'), import('intl/locale-data/jsonp/de.js')]),
)
.then(() => render(translationMessages))
.catch(err => {
throw err;
});
} else {
render(translationMessages);
}
// Install ServiceWorker and AppCache in the end since
// it's not most important operation and if main code fails,
// we do not want it installed
if (process.env.NODE_ENV === 'production') {
require('offline-plugin/runtime').install(); // eslint-disable-line global-require
}
Global Store Js
/**
* Create the store with asynchronously loaded reducers
*/
import { createStore, applyMiddleware, compose } from 'redux';
import { fromJS } from 'immutable';
import { routerMiddleware } from 'react-router-redux';
import createSagaMiddleware from 'redux-saga';
import createReducer from './reducers';
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web and AsyncStorage for react-native
const sagaMiddleware = createSagaMiddleware();
export default function configureStore(initialState = {}, history) {
// Create the store with two middlewares
// 1. sagaMiddleware: Makes redux-sagas work
// 2. routerMiddleware: Syncs the location/URL path to the state
const middlewares = [
sagaMiddleware,
routerMiddleware(history),
];
const enhancers = [
applyMiddleware(...middlewares),
];
// If Redux DevTools Extension is installed use it, otherwise use Redux compose
/* eslint-disable no-underscore-dangle */
const composeEnhancers =
process.env.NODE_ENV !== 'production' &&
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ : compose;
/* eslint-enable */
const store = createStore(
persistReducer({ key: 'root', storage }, createReducer()),
fromJS(initialState),
composeEnhancers(...enhancers)
);
let persistor = persistStore(store);
// Extensions
store.runSaga = sagaMiddleware.run;
store.asyncReducers = {}; // Async reducer registry
// Make reducers hot reloadable, see http://mxs.is/googmo
/* istanbul ignore next */
if (module.hot) {
module.hot.accept('./reducers', () => {
import('./reducers').then((reducerModule) => {
const createReducers = reducerModule.default;
const nextReducers = createReducers(store.asyncReducers);
store.replaceReducer(nextReducers);
});
});
}
return { store, persistor }
}
Global Reduxer JS
Содержимое файла Reduxer
/**
* Combine all reducers in this file and export the combined reducers.
* If we were to do this in store.js, reducers wouldn't be hot reloadable.
*/
import { fromJS } from 'immutable';
import { combineReducers } from 'redux-immutable';
import { LOCATION_CHANGE } from 'react-router-redux';
import appReducer from 'containers/App/reducer';
import languageProviderReducer from 'containers/LanguageProvider/reducer';
/*
* routeReducer
*
* The reducer merges route location changes into our immutable state.
* The change is necessitated by moving to react-router-redux@4
*
*/
// Initial routing state
const routeInitialState = fromJS({
locationBeforeTransitions: null,
});
/**
* Merge route into the global application state
*/
function routeReducer(state = routeInitialState, action) {
switch (action.type) {
/* istanbul ignore next */
case LOCATION_CHANGE:
return state.merge({
locationBeforeTransitions: action.payload,
});
default:
return state;
}
}
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web and AsyncStorage for react-native
/**
* Creates the main reducer with the asynchronously loaded ones
*/
export default function createReducer(asyncReducers) {
return combineReducers({
route: routeReducer,
global: appReducer,
language: languageProviderReducer,
...asyncReducers,
});
}