I'm trying to utilize the React router package in my React + Redux application, and doing so gives me the following errors:
Unexpected key "listings" found in previous state received by the reducer. Expected to find one of the known reducer keys instead: "routing". Unexpected keys will be ignored.
Uncaught TypeError: Cannot read property 'accounts' of undefined
ReactDOMComponentTree.js?1a2c:107Uncaught TypeError: Cannot read property '__reactInternalInstance$c5skqk6ty0f83o5hzvf0i19k9' of null
Here is my code:
initialState.js:
export default {
listings: {
status: '',
searchBy: '',
accounts: []
}
};
index.js (root reducer file):
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
const rootReducer = combineReducers({
routing: routerReducer
});
export default rootReducer;
routes.js:
import React from 'react';
import { Route, IndexRoute } from 'react-router';
import App from './components/App';
export default (
<Route path="/" component={App}>
<IndexRoute component={App}/>
</Route>
);
configureStore.js:
import {createStore, compose, applyMiddleware} from 'redux';
import rootReducer from '../reducers';
import reduxImmutableStateInvariant from 'redux-immutable-state-invariant';
import thunk from 'redux-thunk';
export default function configureStore(initialState) {
const store = createStore(rootReducer, initialState, compose(
// Add other middleware on this line...
applyMiddleware(reduxImmutableStateInvariant(), thunk),
window.devToolsExtension ? window.devToolsExtension() : f => f // add support for Redux dev tools
)
);
if (module.hot) {
// Enable Webpack hot module replacement for reducers
module.hot.accept('../reducers', () => {
const nextReducer = require('../reducers').default; // eslint-disable-line global-require
store.replaceReducer(nextReducer);
});
}
return store;
}
index.js (entry point for app):
import React from 'react';
import {render} from 'react-dom';
import { Provider } from 'react-redux';
import { Router, browserHistory } from 'react-router';
import routes from './routes';
import configureStore from './store/configureStore';
import initialState from './reducers/initialState';
import objectAssign from 'object-assign';
import mockTableData from './data/MockTableData';
import App from './components/App';
import { syncHistoryWithStore } from 'react-router-redux';
const listings = objectAssign({}, initialState.listings, {accounts: mockTableData});
const initial = objectAssign({}, initialState, {listings});
const store = configureStore(initial);
const history = syncHistoryWithStore(browserHistory, store);
render(
<Provider store={store}>
<Router history={history} routes={routes} />
</Provider>, document.getElementById('app')
);
Any ideas?
Related
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import App from './App'
import { Provider } from 'react-redux'
import store from './store'
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>,
document.getElementById('root')
)
store.js
import { createStore, combineReducers } from 'redux'
import thunk from 'redux-thunk'
import { composeWithDevTools } from 'redux-devtools-extension'
import { bookReducers } from './reducers/bookReducers'
const reducer = combineReducers({
book: bookReducers,
})
const middleware = [thunk]
const initialState = {
books: [],
isLoading: false,
eror: '',
}
const store = createStore(
reducer,
initialState,
composeWithDevTools(...middleware)
)
export default store
error I got in my console
I got this error from provider component while adding prop store but its the same as in redux docs . what is happening here
I got - Error: Could not find router reducer in state tree, it must be mounted under "router".
I've read all the similar topics. Tryed different variants, but can't find solution. I still don't have enough knowledge to understand the subject. Plz help to fix this error if you know how.
index.js
import { render } from 'react-dom';
import { Provider, ReactReduxContext } from 'react-redux';
import React from 'react';
import { store, history} from './store';
import { Route, Switch } from 'react-router-dom';
import { ConnectedRouter } from 'connected-react-router'
import App from './components/App/App';
render(
<Provider store={store}>
<ConnectedRouter history={history} context={ReactReduxContext}>
<Switch>
<Route path="/" component={App} />
</Switch>
</ConnectedRouter>
</Provider>,
document.getElementById('root')
);
part of reducers.js
import { combineReducers } from 'redux';
import { routerReducer } from 'react-router-redux';
export default combineReducers({
router: routerReducer
});
store.js
import { applyMiddleware, createStore } from 'redux';
import { createLogger } from 'redux-logger';
import { promiseMiddleware, localStorageMiddleware } from './middleware';
import reducer from './reducers/reducers';
import { routerMiddleware } from 'react-router-redux'
import { createBrowserHistory } from 'history';
export const history = createBrowserHistory();
const getMiddleware = () => applyMiddleware(
routerMiddleware(history), promiseMiddleware, localStorageMiddleware, createLogger()
);
export const store = createStore(
reducer,
getMiddleware(),
);
tryed do like this:
in store.js
import { applyMiddleware, createStore } from 'redux';
import { createLogger } from 'redux-logger';
import { promiseMiddleware, localStorageMiddleware } from './middleware';
import reducer from './reducers/reducers';
import { createBrowserHistory } from 'history';
import { routerMiddleware } from 'connected-react-router';
export const history = createBrowserHistory();
const myRouterMiddleware = routerMiddleware(history);
const getMiddleware = () => applyMiddleware(
myRouterMiddleware, promiseMiddleware, localStorageMiddleware, createLogger()
);
export const store = createStore(
reducer(history),
getMiddleware()
);
in reducers.js
import authorization from './authorization';
import mainstate from './mainstate';
import home from './home';
import { combineReducers } from 'redux';
import { connectRouter } from 'connected-react-router'
export default (history) => combineReducers({
authorization,
mainstate,
home,
router: connectRouter(history)
});
got the same error :(
There are a couple of issues.
createStore(reducer, getMiddleware()) - the enhancer (middleware) needs to be the third argument, the second argument should be the store's initial state. See the docs here.
Try this instead
createStore(reducer, {}, getMiddleware())
The other issue is the version of the history package, with react-router-dom v5 you need to use history v4 (the latest version of which is 4.10.1) - history v5 is only compatible with react-router-dom v6.
In the Codesandbox you posted in your comment below, changing the following in package.json makes it work
"dependencies": {
...
"history": "^5.0.0", -> "history": "4.10.1",
...
}
Lot of solutions out there are pointing at history library version.
The version 5.x of the history package is causing the issues as above.
Could you please try downgrading the history version to 4.10.1 as suggested here
I try to write bellow code. but redux-thunk doesn't work.
Do you know how to resolve it?
When I exec this code, it can get this error.
createStore.js:113 Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.
But I already installed redux-thunk. why does this error happen?
index.js
import { createDevTools } from 'redux-devtools';
import LogMonitor from 'redux-devtools-log-monitor';
import DockMonitor from 'redux-devtools-dock-monitor';
import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import { Provider } from 'react-redux';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import { syncHistoryWithStore, routerReducer } from 'react-router-redux';
import thunk from 'redux-thunk';
import * as storage from './persistence/storage';
import randomToken from './utlis/random';
import * as reducers from './reducers';
import {
App,
Home
} from './components';
const reducer = combineReducers({
...reducers,
routing: routerReducer
});
if (!storage.get('token')) {
storage.put('token', randomToken());
}
const initialState = {
application: {
token: storage.get('token')
}
};
const DevTools = createDevTools(
<DockMonitor toggleVisibilityKey="ctrl-h" changePositionKey="ctrl-q">
<LogMonitor theme="tomorrow" preserveScrollTop={false} />
</DockMonitor>
);
const store = createStore(
reducer,
initialState,
compose(
applyMiddleware(
thunk
),
DevTools.instrument()
)
);
const history = syncHistoryWithStore(browserHistory, store);
ReactDOM.render(
<Provider store={store}>
<div>
<Router history={history}>
<Route path="/" component={App}>
<IndexRoute component={Home}/>
</Route>
</Router>
</div>
</Provider>,
document.getElementById('app')
);
Map.js
import React from 'react';
import { connect } from 'react-redux';
import * as actions from '../actions/cityForcast';
export class Home extends React.Component {
constructor (props, context) {
super(props, context);
}
componentWillMount () {
this.props.dispatch(actions.search(this.props.token));
}
render() {
return (
<div>
<button onClick={() => actions.search()}>Search</button>
</div>
);
}
}
export default connect(({ application, cityForecast }) => ({ application, cityForecast }))(Home);enter code here
cityForcast.js
export function search(token) {
return dispatch => {
console.log(token);
};
}
I could resolve that for myself. I needed to install redux-thunk as devDependencies as well.
I am unable to use redux-devtools-extension with react-router-redux's syncHistoryWithStore. The error i get is Uncaught TypeError: store.getState is not a function.
syncHistoryWithStore # sync.js:38
(anonymous function) # store.js:30
my store.js
import { createStore, applyMiddleware, compose } from 'redux';
import { syncHistoryWithStore } from 'react-router-redux';
import { browserHistory } from 'react-router';
import thunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger';
import rootReducer from './reducers/reducers';
import devTools from 'remote-redux-devtools';
const loggerMiddleware = createLogger()
import data from './dummydata/data'
// dummy data is an export of an array of objects
//
// {
// const data = [
// {
// "Id":"BAcyDyQwcXX",
// "labels": ['P1', 'P2', 'P3', 'P4', 'P5/P6'],
// "series": [[1, 2, 3, 4, 5]],
// "total": 0
// }
// ]
// }
const initialState = {
data
};
//const store = createStore(rootReducer, initialState)
//it works when i use this, but when try to implement the devTools extension,
//the error fires.
const store = function configureStore(initialState) {
const storeCreator = createStore(rootReducer, initialState,
window.devToolsExtension && window.devToolsExtension()
);
return storeCreator;
}
export const history = syncHistoryWithStore(browserHistory, store)
export default store;
my rootReducer.js
import { combineReducers } from 'redux'
import { routerReducer } from 'react-router-redux';
function post(state = [], action) {
console.log("state: ", state, "action: ", action);
return state
}
const rootReducer = combineReducers({
post, routing: routerReducer
})
export default rootReducer
my main.js
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import css from './styles/stylesheets/style.css';
import store, { history } from './store';
import Main from './components/Main';
import Index from './components/Index';
import Single from './components/Single';
import GraphChart from './components/GraphChart';
import { Router, Route, IndexRoute } from 'react-router';
const router = (
<Provider store={store}>
<Router history={history}>
<Route path="/" component={Main}>
<IndexRoute component={GraphChart}></IndexRoute>
<Route path="/view" component={Single}></Route>
</Route>
</Router>
</Provider>
)
render(router, document.querySelector('#react-container'));
I think the problem here is that your store is a function that creates the actual store when you call it and is not the instance of a store.
Try something like this. Export configureStore as a function in myStore.js
import { createStore, applyMiddleware, compose } from 'redux';
import thunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger';
import rootReducer from './reducers/reducers';
import devTools from 'remote-redux-devtools';
const loggerMiddleware = createLogger()
export default function configureStore(initialState) {
const storeCreator = createStore(rootReducer, initialState,
window.devToolsExtension && window.devToolsExtension()
);
return storeCreator;
}
and in your main.js import the configureStore and create the store with the initial data from here. Once you get the instance of the store you can synchHistoryWithStore here.
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import data from './dummydata/data'
import css from './styles/stylesheets/style.css';
import createStore from './store';
import { browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import Main from './components/Main';
import Index from './components/Index';
import Single from './components/Single';
import GraphChart from './components/GraphChart';
import { Router, Route, IndexRoute } from 'react-router';
const initialState = {
data
};
const store = createStore(initialData)
const history = syncHistoryWithStore(browserHistory, store);
const router = (
<Provider store={store}>
<Router history={history}>
<Route path="/" component={Main}>
<IndexRoute component={GraphChart}></IndexRoute>
<Route path="/view" component={Single}></Route>
</Route>
</Router>
</Provider>
)
render(router, document.querySelector('#react-container'));
I tried to create a simple react-redux-ajax working example, following Reddit API tutorial, but I get this error:
Uncaught Error: Actions may not have an undefined "type" property. Have you misspelled a constant?
The error is thrown by:
dispatch(fetchProducts(this.props)); in App.jsx
index.jsx
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { compose, createStore, applyMiddleware } from 'redux'
import { Provider } from 'react-redux';
import thunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger';
import { createDevTools, persistState} from 'redux-devtools';
import DevTools from './DevTools.jsx';
import App from './App.jsx';
import rootReducer from './reducers.js';
const loggerMiddleware = createLogger();
function configureStore(initialState) {
return createStore(
rootReducer,
initialState,
DevTools.instrument(),
applyMiddleware(
thunkMiddleware,
loggerMiddleware
),
// Lets you write ?debug_session=<name> in address bar to persist debug sessions
persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))
)
}
const store = configureStore();
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>, document.getElementsByClassName('products')[0]);
You just forgot to compose your enhancers, the third argument to createStore must be a function so you need to compose all your enhancers to provide a unique enhancer :
index.jsx
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import { compose, createStore, applyMiddleware } from 'redux'
import { Provider } from 'react-redux';
import thunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger';
import { createDevTools, persistState} from 'redux-devtools';
import DevTools from './DevTools.jsx';
import App from './App.jsx';
import rootReducer from './reducers.js';
const loggerMiddleware = createLogger();
function configureStore(initialState) {
return createStore(
rootReducer,
initialState,
compose(
applyMiddleware(
thunkMiddleware,
loggerMiddleware
),
DevTools.instrument(),
persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))
)
)
}
const store = configureStore();
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>, document.getElementsByClassName('products')[0]);
Redux DevTool doc