I'm trying to implement redux in my universal app, but I've some problems with redux.
I've this configureStore function:
import { createStore, applyMiddleware, compose } from 'redux';
import thunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger'
import rootReducer from '../reducers/index';
import { routerMiddleware } from 'react-router-redux';
export default function configureStore(history, initialState) {
const reduxRouterMiddleware = routerMiddleware(history);
let finalCreateStore;
if (__DEVELOPMENT__ && __CLIENT__ && __DEVTOOLS__) {
const { persistState } = require('redux-devtools');
const DevTools = require('../containers/DevTools/DevTools');
finalCreateStore = compose(
applyMiddleware(thunkMiddleware)(createStore),
window.devToolsExtension ? window.devToolsExtension() : DevTools.instrument(),
persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))
)(createStore);
}
else {
finalCreateStore = applyMiddleware(thunkMiddleware)(createStore);
}
const store = finalCreateStore(rootReducer, initialState);
if (__DEVELOPMENT__ && module.hot) {
module.hot.accept(rootReducer, () => {
store.replaceReducer(rootReducer);
});
}
return store;
}
And then I've my rootReducer file that looks like this:
import { combineReducers } from 'redux';
import environment from './environment';
import general from './general';
import alert from './alert';
import user from './user';
import { routerReducer } from 'react-router-redux'
const rootReducer = combineReducers({
environment,
general,
alert,
user,
routing: routerReducer
});
export default rootReducer;
The problem is that I get this error: Expected the reducer to be a function.
I've googled and searched on StackOverflow(where there are some similar problems), but the answers doesn't works in my case.
So, what I'm doing wrong ? and why ?
Thanks.
try this:
finalCreateStore = compose(
// you write more than one createStore here
applyMiddleware(thunkMiddleware),
window.devToolsExtension ? window.devToolsExtension() : DevTools.instrument(),
persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/))
)(createStore);
Have you tried
import { combineReducers } from 'redux';
import environment from './environment';
import general from './general';
import alert from './alert';
import user from './user';
import { routerReducer } from 'react-router-redux'
export const rootReducer = combineReducers({
environment: environment,
general: general,
alert: alert,
user: user,
routing: routerReducer
});
export default rootReducer;
Related
I am switching my redux-react app to gatsby app , I am facing this issue
and I cannot see the pages anymore.
I've tried to follow these instructions : https://github.com/gatsbyjs/gatsby/tree/master/examples/using-redux
yet I get this problem.
createStore.js :
import { createStore, applyMiddleware } from 'redux'
import logger from 'redux-logger'
import createSagaMiddle from 'redux-saga'
import rootSaga from './rootSaga'
import rootReducer from './rootReducer'
import thunk from 'redux-thunk';
const sagaMiddleware = createSagaMiddle()
export const middlewares = [thunk,sagaMiddleware,logger];
export const store = createStore(rootReducer, applyMiddleware(...middlewares))
sagaMiddleware.run(rootSaga)
export default store;
rootReducer.js:
import { combineReducers } from 'redux'
import userReducer from './User/user.reducer'
export default combineReducers({
user: userReducer
})
wrap-with-provider.js:
import * as React from 'react';
import { Provider } from 'react-redux';
import store from './src/state/createStore'
const wrapWithProvider = ({ element }) => (
<Provider store={store}>{element}</Provider>
);
export default wrapWithProvider
and gatsby-ssr.js / gatsby-browser.js:
import wrapWithProvider from "./wrap-with-provider"
export const wrapRootElement = wrapWithProvider
what probably could be the reason.
I removed brackets({}) in import and that fixed my problem. You can try this: import createStore from 'redux'
Hey I've looked at a bunch of help files now and cant seem to get the issue solved. Most suggestions are using a different setup than I have. The main issue that the others dont have is the LOGOUT feature. Can you suggest another way to handle the LOGOUT?
Here is my index.js for "combine reducers":
import { combineReducers } from 'redux';
import { connectRouter } from 'connected-react-router';
import { LOGOUT_USER } from '../constants/index';
/* App Reducer Files */
import app from './app/reducer';
import accountData from './account/reducer';
import employeeData from './employee/reducer';
import locationData from './location/reducer';
import googleData from './google/reducer';
import requestData from './request/reducer';
import menuItemData from './menuItem/reducer';
import orderData from './order/reducer';
/* Public Reducer Files */
import valorData from './valor/reducer';
const appReducer = history => combineReducers({
router: connectRouter(history),
app,
accountData,
employeeData,
locationData,
googleData,
requestData,
menuItemData,
orderData,
// Public
valorData,
});
const rootReducer = history => (state, action) => {
if (action.type === LOGOUT_USER) {
state = undefined;
}
return appReducer(history, state, action);
};
export default rootReducer;
And my store.js:
import { createStore, applyMiddleware, compose } from 'redux';
import thunkMiddleware from 'redux-thunk';
import { createLogger } from 'redux-logger';
import { routerMiddleware } from 'connected-react-router';
import rootReducer from '../services';
import history from '../history';
const debugware = [];
if (process.env.NODE_ENV !== 'production') {
debugware.push(createLogger({
collapsed: true,
}));
}
export default function configureStore(initialState) {
const store = createStore(
rootReducer(history),
initialState,
compose(
applyMiddleware(
routerMiddleware(history),
thunkMiddleware,
...debugware,
),
),
);
if (module.hot) {
// Enable Webpack hot module replacement for reducers
module.hot.accept('../services', () => {
const nextRootReducer = require('../services/index').default;
store.replaceReducer(nextRootReducer);
});
}
return store;
}
This was working before I upgraded to a new router version. Again the main issue is the LOGOUT. If I just export appReducer it works just fine but doesnt logout.
WOW. The moment I post it I try one more thing...
const rootReducer = history => (state, action) => {
if (action.type === LOGOUT_USER) {
state = undefined;
}
return appReducer(history)(state, action);
};
Why are you returning an undefined state? Instead, return
if (action.type === LOGOUT_USER) {
return{ ...state, user: [] }
}
It basically returns and empty array as user.
I am trying to get a redux-form working but am getting a warning that says:
Unexpected property "form" found in previous state received by the reducer. Expected to find one of the known reducer property names instead: "route", "questionSet". Unexpected properties will be ignored.
When I console.log the props to see my form, form is undefined.
I believe the problem is in the configuration.
my index.js:
import React from 'react';
import ReactDOM from 'react-dom';
import 'babel-polyfill';
import './index.css';
import App from './containers/App/App';
import registerServiceWorker from './registerServiceWorker';
import { Provider } from 'react-redux';
import configureStore from './configureStore'
import createHistory from 'history/createBrowserHistory';
// import { configureStore } from "redux-inject-reducer-and-saga";
const initialState = {};
const history = createHistory();
const store = configureStore(initialState, createHistory);
ReactDOM.render( <Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
registerServiceWorker();
this is my storeConfig.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 './rootReducer';
const sagaMiddleware = createSagaMiddleware();
export default function configureStore(initialState, history) {
const middlewares = [sagaMiddleware, routerMiddleware(history)];
const enhancers = [applyMiddleware(...middlewares)];
const composeEnhancers =
process.env.NODE_ENV !== 'production' &&
typeof window === 'object' &&
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
shouldHotReload: false,
})
: compose;
const store = createStore(
createReducer(),
fromJS(initialState),
composeEnhancers(...enhancers),
);
store.runSaga = sagaMiddleware.run;
store.injectedReducers = {};
store.injectedSagas = {};
if (module.hot) {
module.hot.accept('./rootReducer', () => {
store.replaceReducer(createReducer(store.injectedReducers));
});
}
return store;
}
This is my RootReducer:
import { fromJS } from 'immutable';
import { combineReducers } from 'redux-immutable';
// import { routeReducer } from 'react-router-redux';
import {reducer as formReducer} from 'redux-form/immutable';
export default function createReducer(injectedReducers) {
console.log(formReducer, 'form')
return combineReducers({
// route: routeReducer,
...injectedReducers,
form: formReducer
});
}
Need more text to post (will replace): I can also add the rootReducer in a minute.I can also add the rootReducer in a minute.I can also add the rootReducer in a minute.I can also add the rootReducer in a minute.I can also add the rootReducer in a minute.I can also add the rootReducer in a minute.I can also add the rootReducer in a minute.I can also add the rootReducer in a minute.I can also add the rootReducer in a minute.I can also add the rootReducer in a minute.I can also add the rootReducer in a minute.
I'm following the following tutorial:
https://medium.com/react-native-training/tutorial-react-native-redux-native-mobile-app-for-tracking-cryptocurrency-bitcoin-litecoin-810850cf8acc
When I run my app, I get the following error message:
Unable to resolve ./Reducers" from
"./C:\Users\Bryan\Documents\React-native\AwesomeProject\src\Store.js:
could not resolve
C:\Users\Bryan\Documents\React-native\AwesomeProject\src\Reducers'
as a file nor as a
folder","name":"UnableToResolveError","type":"UnableToResolveError","errors":[{}]},"type":"bundling_error"}"
Here Is my Store.js
import { Platform } from 'react-native';
import {
createStore,
applyMiddleware,
compose
} from 'redux';
import devTools from 'remote-redux-devtools';
import promise from 'redux-promise';
import thunk from 'redux-thunk';
import logger from 'redux-logger';
import RootReducer from './Reducers';
const middleware = applyMiddleware(thunk, promise, logger);
const Store = createStore (
RootReducer,
compose(
middleware,
devTools({
name: Platform.OS,
hostname: 'localhost',
port: 5678
}),
)
);
export default Store;
And in my Reducers-folder, I have the following files:
CryptoReducer.js
export default function(state = [], action) {
return state;
}
Index.js
import {combineReducers} from 'redux';
import CryptoReducer from './CryptoReducer.js';
export default combineReducers({
crypto: CryptoReducer
});
Why do I get this error? Why is it not working and how can I to solve this?
I am learning redux and wanted to know how can I save the state locally so when I refresh after making some changes to state it remains. I came to know about redux-persist and saw the github doc describing how to use it but its not very clear to me.
Here is the index.js code of my app -
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import App from './components/app';
import reducers from './reducers';
const createStoreWithMiddleware = applyMiddleware()(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<App />
</Provider>
, document.querySelector('#container'));
How can I achieve it ?
//In your createStore have this code
import { applyMiddleware, compose, createStore } from 'redux'
import thunkMiddleware from 'redux-thunk';
import { createLogger } from 'redux-logger';
import rootReducer from '../reducers';
import { persistReducer } from 'redux-persist'
import localForage from 'localforage';
const loggerMiddleware = createLogger();
export default (initialState = {}) => {
// ======================================================
// Middleware Configuration
// ======================================================
const middleware = [thunkMiddleware, loggerMiddleware]
// ======================================================
// Store Enhancers
// ======================================================
const enhancers = []
const __DEV__ = process.env.NODE_ENV !== 'production';
if (__DEV__) {
const devToolsExtension = window.devToolsExtension
if (typeof devToolsExtension === 'function') {
enhancers.push(devToolsExtension())
}
}
// ======================================================
// Store Instantiation and HMR Setup
// ======================================================
let config = {
key: 'root',
storage: localForage,
whitelist: ['user'],
debug: __DEV__
}
let configureReducer = persistReducer(config, rootReducer)
const store = createStore(
configureReducer,
initialState,
compose(
applyMiddleware(...middleware),
...enhancers
),
)
return store
}
// In your App.js or root app, do this in your componentDidMount
persistStore(
store,
undefined,
() => {
console.log('callback::')
}
)
Here is what you should do for creating your store, using redux-persist in store.js:
import { createStore, applyMiddleware, compose, combineReducers } from 'redux';
import { persistStore, autoRehydrate } from 'redux-persist';
import localForage from 'localforage';
import { routerReducer } from 'react-router-redux';
import reducers from './container/reducers';
import middlewares from './middlewares';
const reducer = combineReducers({
...reducers,
routing: routerReducer,
});
export const initStore = (state) => {
const store = createStore(
reducer,
{},
compose(
applyMiddleware(...middlewares),
autoRehydrate(),
),
);
persistStore(store, {
storage: localForage,
whitelist: ['login'],
});
return store;
};
In your app.js, create your store this way:
import React from 'react';
import { Provider } from 'react-redux';
import { browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import createRoutes from './routes'; // Contains the routes
import { initStore, persistReduxStore } from './store';
import { appExample } from './container/reducers';
const store = initStore(appExample);
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = { rehydrated: false };
}
componentWillMount() {
persistReduxStore(store)(() => this.setState({ rehydrated: true }));
}
render() {
const history = syncHistoryWithStore(browserHistory, store);
return (
<Provider store={store}>
{createRoutes(history)}
</Provider>
);
}
}