Here is my code:
store.js
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';
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)];
const store = createStore(createReducer, fromJS(initialState), enhancers);
// Extensions
store.runSaga = sagaMiddleware.run;
store.asyncReducers = {}; // Async reducer registry
return store;
}
Routes.js
import React from 'react';
import {Route, Router, IndexRoute, browserHistory} from 'react-router';
import {syncHistoryWithStore} from 'react-router-redux';
import store from './store';
import Welcome from './containers/Welcome';
const history = syncHistoryWithStore(browserHistory, store);
const routes = (
<Router history={history}>
<Route path="/">
<IndexRoute component={Welcome} />
</Route>
</Router>
);
export default routes;
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {browserHistory} from 'react-router';
import { Providers } from 'react-redux';
import configureStore from './store';
import routes from './routes';
const initialState = {};
const store = configureStore(initialState, browserHistory);
ReactDOM.render(
<Provider store={store}>
{routes}
</Provider>, document.getElementById('main-content')
);
I can't find where the culprit is. I tried to debug it, but can't found what really make it those error. error: Uncaught TypeError: store.getState is not a function
Any solution?
This is a typo that generated the error: TypeError: store.getState is not a function
Wrong
const store = createStore(()=>[], {}, applyMiddleware);
Correct
const store = createStore(()=>[], {}, applyMiddleware());
Notice the added parenthesis () on applyMiddleware.
in my case i got this error because my store was as shown below which is a function:
const store = preloadedState => {
let initialState={}
//some code to modify intialState
return createStore(reducer, initialState)
}
but in index.js i was passing store as a function and not the value it was returning.
wrong
<Provider store={store}>
<MyApp />
</Provider>
correct
<Provider store={store()}>
<MyApp />
</Provider>
Notice that in your Routes.js the store is not being initialized properly. You should add these lines:
const initialState = {};
const store = configureStore(initialState, browserHistory);
as in your index.js file.
I was doing this (a dynamic require) ..
const store = require('../store/app')
state = store.getState()
but for some reason when using require instead of import you have to do this ..
const store = require('../store/app')
state = store.default.getState()
Not sure if this will help but you named your import { Providers } instead of { Provider } from react-redux library.
In index.js we have to provide store() method as props value instead of store.
<Provider store={store()}>
{routes}
</Provider>
Updated index.js file.
import React from 'react';
import ReactDOM from 'react-dom';
import {browserHistory} from 'react-router';
import { Providers } from 'react-redux';
import configureStore from './store';
import routes from './routes';
const initialState = {};
const store = configureStore(initialState, browserHistory);
ReactDOM.render(
<Provider store={store()}>
{routes}
</Provider>, document.getElementById('main-content')
);
this is the solution, good luck 🤞
import { applyMiddleware, combineReducers, createStore } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from 'redux-thunk'
const reducer = combineReducers({
products: []
})
const middleware = [thunk]
const store = createStore(
reducer,
composeWithDevTools(applyMiddleware(...middleware))
)
export default store
TypeError: store.getState is not a function -This error often occurs when you are not properly initializing middleware function. What you need to do is as below
You need to add paranthesis on applyMiddleware ( ) function and then it will behave as you are expecting it to do.
const store = createStore(()=>[], {}, applyMiddleware());
Replacing store with store() worked for me. Written below:
<Provider store={store()}>
{routes}
</Provider>
Related
As the title says, I'm mapping through an array I have from an api in UserCardList component and it works fine but once I wrap App with PersistGate, it gives me "TypeError: users.map is not a function" and the error message from redux logger is "redux-persist: persist timed out for persist key "root". I really don't know what I'm doing wrong.
Any help would be highly appreciated.
index.js
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { store, persistor } from "./redux/store";
import "./index.css";
import "tachyons";
import App from "./containers/App";
ReactDOM.render(
<Provider store={store}>
<BrowserRouter>
<PersistGate persistor={persistor}>
<App />
</PersistGate>
</BrowserRouter>
</Provider>,
document.getElementById("root")
redux store
import { createStore, applyMiddleware } from "redux";
import { persistStore } from "redux-persist";
import thunkMiddleware from "redux-thunk";
import { createLogger } from "redux-logger";
import rootReducer from "../redux/root-reducer";
const logger = createLogger();
const middlewares = [logger, thunkMiddleware];
export const store = createStore(rootReducer, applyMiddleware(...middlewares));
export const persistor = persistStore(store);
export default { store, persistor };
root-reducer
import { combineReducers } from "redux";
import { persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import requestUsers from "./reducers";
const persistConfig = {
key: "root",
storage,
whitelist: ["users"],
};
const rootReducer = combineReducers({
users: requestUsers,
});
export default persistReducer(persistConfig, rootReducer);
UserCardList component
import React, { Fragment } from "react";
import UserCard from "./UserCard";
const UserCardList = ({ users }) => {
return (
<Fragment>
<h1 className="f1"> Users </h1>
{users.map((user) => {
return (
<UserCard
key={user.login.uuid}
image={user.picture.large}
firstName={user.name.first}
lastName={user.name.last}
email={user.email}
city={user.location.city}
country={user.location.country}
/>
);
})}
</Fragment>
);
};
export default UserCardList;
I have created a sample project here by taking the code from your question and everything looks fine for me. And the store is getting created and users is coming as expected.
There could be a possible error in the reducers which is not posted here. Please have a look at the sample project, hope it helps.
I see in redux store you have this:
export const store = createStore(rootReducer, applyMiddleware(...middlewares));
export const persistor = persistStore(store);
// you dont need line below, you exported store and persistore in lines above
export default { store, persistor };
In my case, adding timeout: null to the persist configuration solved my issue.
const persistConfig = {
key: 'keyOfStore',
storage: storage,
// There is an issue in the source code of redux-persist (default setTimeout does not cleaning)
timeout: null,
}
const appReducer = combineReducers({
...otherReducers,
keyOfStore: persistReducer(persistConfig, keyOfStoreRedfucer),
})
Got the solution from here
Here is my code:
store.js
import { createStore, applyMiddleware, compose } from "redux";
import thunk from "redux-thunk";
import rootReducer from "./reducers";
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(...middleware),
(window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__()) ||
compose
)
);
App.js
import React, { Component } from 'react';
import './sass/main.scss';
import { BrowserRouter as Router, Route } from "react-router-dom";
import Landing from './components/pages/Landing';
import { Provider } from "react-redux";
import store from "../src/store";
import Register from "./components/auth/Register";
import Login from "./components/auth/Login";
class App extends Component {
render() {
return (
<Provider store={store}>
<Router>
<div className="App">
<Route exact path='/' component={Landing}/>
<Route exact path="/login" component={Login}/>
<Route exact path="/register" component={Register}/>
</div>
</Router>
</Provider>
);
}
}
export default App;
I can't find where the problem is. I tried to debug it, but can't found what really make it those error. error: Uncaught TypeError: store.getState is not a function.
./src/App.js
Attempted import error: '../src/store' does not contain a default export (imported as 'store').
The first thing tried is adding a export default createStore but that bring up other error message saying Line 10: 'store' is assigned a value but never used and TypeError: store.getState is not a function
In your App.js you are trying to import store from "../src/store";. So system will try to import something from ../src/store.js but you never export any variable in that file.
You can update store.js to add export statement
const store = createStore(
rootReducer,
initialState,
compose(
applyMiddleware(...middleware),
(window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__()) ||
compose
)
);
export default store;
I'm using redux-persist and I'm trying to render a screen passing it to the loading prop of PersistGate.
I did some research and I found that I should dispatch REHYDRATE to the reducer but that doesn't work either.
Maybe I'm not configuring my reducers well?
I would also like to be able to set the loading prop to null to avoid the flash screen before the App renders, but the result is the same as passing it a component to render.
This is my code of index.js
import App from './App';
import React from 'react';
import { Provider } from 'react-redux';
import { AppRegistry } from 'react-native';
import { PersistGate } from 'redux-persist/integration/react';
import { SplashScreen } from './src/screens/SplashScreen';
import configureStore from './src/store/configureStore';
const store = configureStore();
const persistor = configureStore();
const RNRedux = () => (
<Provider store={store}>
<PersistGate loading={<SplashScreen/>} persistor={persistor}>
<App />
</PersistGate>
</Provider>
);
componentDidMount = () => {
this.persistor.dispatch({ type: REHYDRATE });
};
AppRegistry.registerComponent('Sharryapp', () => RNRedux);
And that's my configureStore file:
import { createStore, combineReducers, applyMiddleware} from 'redux';
import ServerReducer from './reducers/ServerReducer';
import InviteReducer from './reducers/InviteReducer';
import { persistStore, persistReducer } from 'redux-persist';
import thunk from 'redux-thunk';
import storage from 'redux-persist/lib/storage';
const rootReducer = combineReducers({
server: ServerReducer,
invite: InviteReducer,
});
const persistConfig = {
key: 'root',
debug: true,
storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer);
const store = createStore(persistedReducer,applyMiddleware(thunk));
const persistor = persistStore(store);
export default configureStore = () => {
return ( store, persistor );
};
I am not sure why you wrap your store and persistor in a configureStore function.
Instead import both separately:
export const store = createStore(persistedReducer,applyMiddleware(thunk));
export const persistor = persistStore(store);
And import them in your desired file:
import {store, persistor} from './src/store/configureStore';
I have also noticed that your createStore call is false, since enhancers are passed as the third parameter. Change it to:
const store = createStore(persistedReducer, undefined, applyMiddleware(thunk));
That should do it.
Also you do not need to dispatch a rehydrate action as it happens automatically on app start.
I just started to use Redux Persist, and for some reason I can't get it to work.
(Cannot read property 'subscribe' of undefined error)
Persistor.js
import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import store from 'redux-persist/es/storage/session' // defaults to
localStorage for web and AsyncStorage for react-native
import rootReducer from './reducers'
const persistConfig = {
key: 'root',
storage: store,
}
const persistedReducer = persistReducer(persistConfig, rootReducer)
export default () => {
let store = createStore(persistedReducer)
let persistor = persistStore(store)
return { store: store, persistor: persistor }
}
index.js
import React from 'react';
import App from './components/App/App';
// import registerServiceWorker from './registerServiceWorker';
import { render } from 'react-dom'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/integration/react'
import persistor from './Persistor'
import rootReducer from './reducers'
import 'bootstrap/dist/css/bootstrap.min.css'
import './index.css'
render(
<Provider store={persistor.persistor}>
<PersistGate loading={null} persistor={persistor.store}>
<App />
</PersistGate>
</Provider>,
document.getElementById('root')
)
with normal Redux its worked properly. But as soon I tried to switch Persist Redux I got the error I write above.
The persistor value you are importing in index isn’t an object. It is a function that returns an object containing store and the persistor.
Instantiate the persistor function and then also swap your values assigned to store in Provider with persistor in persistgate.
Rename your import to something like configureStore to prevent any conflict.
const { store, persistor } = configureStore()
render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>,
document.getElementById('root')
)
Hi I am trying to setup redux-persist with react-redux, but I cant get it to work. I get the following error:
TypeError: _store2.default is not a function [Learn More] index.js:12:29
How I have the setup right now:
store.js
import {applyMiddleware, createStore} from 'redux';
import {persistStore,persistCombineReducers} from 'redux-persist';
import storage from 'redux-persist/es/storage' // default: localStorage if web, AsyncStorage if react-native
import { logger } from 'redux-logger';
import thunk from 'redux-thunk';
import promise from 'redux-promise-middleware';
import reducer from './reducers'
const middleware = applyMiddleware(promise(), thunk, logger);
const config = {
key: 'root',
storage,
};
const reducers = persistCombineReducers(config, {reducer});
export const configureStore = () => {
const store = createStore(reducers, middleware);
const persistor = persistStore(store);
return { persistor, store };
};
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import {BrowserRouter} from 'react-router-dom';
import {Provider} from 'react-redux';
import Bootstrap from 'bootstrap/dist/css/bootstrap.css';
import './css/app.css';
import App from './containers/App';
import { PersistGate } from 'redux-persist/es/integration/react'
import configureStore from './store';
const { persistor, store } = configureStore()
ReactDOM.render(
<Provider store={store} >
<PersistGate persistor={persistor}>
<BrowserRouter>
<App/>
</BrowserRouter>
</PersistGate>
</Provider>,
document.getElementById('root')
);
UPDATE 1
Based on #azium's response now I get:
The above error occurred in the component:
in Connect(App) (created by Route)
in Route (created by withRouter(Connect(App)))
in withRouter(Connect(App))
in Router (created by BrowserRouter)
in BrowserRouter
in PersistGate
in Provider
When calling it like so from App.js:
#withRouter
#connect((store) => {
return {
isAuthenticated: store.auth.isAuthenticated,
};
})
If you want to use the default export you need to change:
export const configureStore = () => {
const store = createStore(reducers, middleware);
const persistor = persistStore(store);
return { persistor, store };
};
to:
export default () => {
const store = createStore(reducers, middleware);
const persistor = persistStore(store);
return { persistor, store };
};
or:
const configureStore = () => {
const store = createStore(reducers, middleware);
const persistor = persistStore(store);
return { persistor, store };
};
export default configureStore;
or if you don't want to use default export change:
import configureStore from './store';
to:
import { configureStore } from './store';
So after a bit of thinkering and community help I managed to narrow down the issue to my reducer declaration. I was declaring reducer in index.js with combineReducers whilst redux-persist says it shouldn't be.
Final index.js code:
import user from './userReducer'
import auth from './authReducer'
export default ({
user, auth
})