import * as actions from '../actions/login.Action';
let initialState = {
user: {
loggedIn: false,
userRole: "",
userEmail: "",
}
};
export default function (state = initialState, action) {
switch (action.type) {
case actions.LOGIN_SUCCESS:
return {
...state,
user: {
...state.user,
loggedIn: true,
userRole: action.userRole,
}
};
case actions.LOGOUT:
return initialState;
default:
return state;
}
}
this is my reducer triggered after the action login success and below is my store code
import { createStore, applyMiddleware, compose } from 'redux';
//import createSagaMiddleware from 'redux-saga';
import { routerMiddleware } from 'react-router-redux';
import thunk from 'redux-thunk';
import createHistory from 'history/createBrowserHistory';
import rootReducer from './reducers';
const enhancers = [];
const middleware = [
thunk,
routerMiddleware(history)
];
export const history = createHistory();
const composedEnhancers = compose(
applyMiddleware(...middleware),
...enhancers
);
export const store = createStore(
rootReducer,
persistedState,
composedEnhancers
);
const persistedState = localStorage.getItem('state') ? JSON.parse(localStorage.getItem('state')) : {};
store.subscribe(() => {
localStorage.setItem('reduxState', JSON.stringify(store.getState()));
});
in this case I am able to get the value from reducer but the issue is state value gets empty on page refresh whats wrong in this code i'm unable to identify clueless why the store doesn't save the state
I think you first call persistedState then define it Look below :
export const store = createStore(
rootReducer,
persistedState,
composedEnhancers
);
const persistedState = localStorage.getItem('state') ?
JSON.parse(localStorage.getItem('state')) : {};
How about to change the position of persistedState so after that you have :
const persistedState = localStorage.getItem('state') ?
JSON.parse(localStorage.getItem('state')) : {};
export const store = createStore(
rootReducer,
persistedState,
composedEnhancers
);
Related
tree structure
i'm using create react app
src/reducers/index.js :
here is my reducer
const initialState = {
menuOpen:false,
};
function reducer (state = initialState, action = {}) {
switch (action.type) {
case 'MENU_CLICKED':
return {
...state,
menuOpen: !state.menuOpen,
};
default:
return state;
}
}
export default reducer;
default export
src/store/index.js :
here is my store
i used relative path for import my reducer
import { createStore, applyMiddleware, compose } from 'redux';
import reducer from 'src/reducers';
//const middlewares = applyMiddleware(lister les Middlewares);
//const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
//const enhancers = composeEnhancers(middlewares);
const store = createStore(reducer);
export default store;
Error :
ERROR in ./src/store/index.js 4:0-35
Module not found: Error: Can't resolve 'src/reducers' in 'C:\Users\apiot\Desktop\NoteToMyself\src\store'
Instead of
import reducer from 'src/reducers';
It should be
import reducer from '../reducers/index.js';
here is my redux store code it gives the input type error or input invalid error
but this error is coming in development mode not on production why it is so, i don't have any clue
import { createStore, applyMiddleware, combineReducers } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import { persistStore, persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import sessionStorage from "redux-persist/lib/storage/session";
import thunk from "redux-thunk";
import rootReducer from "./reducers";
import { createStateSyncMiddleware } from "redux-state-sync";
const SET_CLIENT_STATE = "SET_CLIENT_STATE";
const middlewares = [
thunk,
createStateSyncMiddleware({
// blacklist: ["extras", "products"]
whitelist: ["user"],
}),
];
const persistConfig = {
key: "root",
storage,
whitelist: ["user", "loggedInDoctor", "loggedInPatient"],
};
const sessionRedConfig = {
key: "referrer",
storage: sessionStorage,
};
const { referrer, ...otherReducer } = rootReducer;
const allReducers = combineReducers({
...otherReducer,
referrer: persistReducer(sessionRedConfig, referrer),
});
const persistedReducer = persistReducer(persistConfig, allReducers);
const makeConfiguredStore = (reducer, initialState) =>
createStore(
reducer,
initialState,
composeWithDevTools(applyMiddleware(...middlewares))
);
export const makeStore = (initialState, { isServer, req, debug, storeKey }) => {
if (isServer) {
initialState = initialState || { fromServer: "foo" };
return makeConfiguredStore(allReducers, initialState);
} else {
// we need it only on client side
const store = makeConfiguredStore(persistedReducer, initialState);
store.__persistor = persistStore(store); // Nasty hack
return {
...store,
store,
};
}
};
export const setClientState = (clientState) => ({
type: SET_CLIENT_STATE,
payload: clientState,
});
I have set up my redux store and everything seems alright all imports and exports seems correct to me but I do not seem to have a valid reducer and sagas. Been stuck, what am I doing wrong?
I get this error message
I have a store with the file structure below
Store
configStore.js
index.js
import { applyMiddleware, compose, createStore } from 'redux';
import createSagaMiddleware from 'redux-saga';
import rootReducer from '../components/rootReducer';
export default function configureStore(initialState) {
const sagaMiddleware = createSagaMiddleware();
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
return {
...createStore(
rootReducer,
initialState,
composeEnhancers(applyMiddleware(sagaMiddleware)),
),
runSaga: sagaMiddleware.run,
};
}
import configureStore from './configStore';
import rootSaga from '../components/rootSaga';
const store = configureStore({});
store.runSaga(rootSaga);
export default store;
rootSaga
import { all } from 'redux-saga/effects';
import planets from './planets';
export default function* rootSaga() {
yield all([
planets.sagas(),
]);
}
rootReducer
import { combineReducers } from 'redux';
import planets from './planets';
export default combineReducers({
planets: planets.reducers,
});
In my components I have
reducers.js
import { UPDATE_PLANETS, LOAD_PLANETS } from './actionTypes';
const initialState = {
isPlanetsLoading: false,
planets: [],
};
export default (state = initialState, { type, payload }) => {
switch (type) {
case LOAD_PLANETS:
return {
...state,
isPlanetsLoading: true,
};
case UPDATE_PLANETS:
return {
...state,
isPlanetsLoading: false,
planets: payload,
};
default:
return state;
}
};
Planets.js
import { List } from "antd";
import React, { useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { requestPlanets } from '../actions';
const Planets = () => {
const dispatch = useDispatch();
const { planets } = useSelector(
(state) => state.planets
);
console.log(planets);
useEffect(() => {
dispatch(requestPlanets());
}, [dispatch, planets]);
// return statement
};
export default Planets;
createStore returns the store. So don't spread it. Just associate the output of createStore to an object property say store.
in index.js, destructure the configStore object { store, runSaga }
configStore
export default function configureStore(initialState) {
const sagaMiddleware = createSagaMiddleware();
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
return {
store: createStore(
rootReducer,
initialState,
composeEnhancers(applyMiddleware(sagaMiddleware)),
),
runSaga: sagaMiddleware.run,
};
}
index.js
import configureStore from './configStore';
import rootSaga from '../components/rootSaga';
const { store, runSaga } = configureStore({});
runSaga(rootSaga);
export default store;
INDEX.JS FILE
import { compose, createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import firebase from '../Firebase/Firebase';
import { reactReduxFirebase, getFirebase } from 'react-redux-firebase';
import { reduxFirestore, getFirestore } from 'redux-firestore';
import rootReducer from './reducers';
// react-redux-firebase config
const rrfConfig = {
userProfile: 'users',
useFirestoreForProfile: true, // Firestore for Profile instead of Realtime DB
};
const composeEnhancers =
process.env.NODE_ENV === 'development'
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
: compose;
const store = createStore(
rootReducer,
composeEnhancers(
reactReduxFirebase(firebase, rrfConfig),
reduxFirestore(firebase),
applyMiddleware(thunk.withExtraArgument({ getFirebase, getFirestore }))
)
);
export default store;
I believe my formatting is correct, however, I am lost. Can someone help, please? Below are my two files in my reducers folder.Please feel free to ask any questions you may have, and I will do my best to answer them. I am seriously stuck.
REDUCERS -> AUTHREDUCER.JS
const initialState = {
}
export default(state = initialState, action) => {
return'dhdhdhd';
};
REDUCERS -> INDEX.JS
import {combineReducers} from 'redux';
import { firebaseReducer } from 'react-redux-firebase';
import authReducer from './authReducer';
export default combineReducers({
auth: authReducer,
firebase: firebaseReducer,
});`enter code here`
When running NPM start, I return this error :
"TypeError: Object(...) is not a function" at const store = createStore( .
checkout https://redux.js.org/api/createstore, I believe 2nd argument should be initial state
const initialState = {} // the initial value for your state
const store = createStore(
rootReducer,
initialState, // 2nd argument of createStore is initial state
composeEnhancers(
...
)
);
UPDATED:
checkout http://docs.react-redux-firebase.com/history/v3.0.0/docs/v3-migration-guide.html#remove-store-enhancer as they have deprecated the enhancer for react-redux-firebase
so
Remove the reactReduxFirebase from the enhancers
Use the ReactReduxFirebaseProvider
const rrfProps = {
...
};
const App = () => (
<Provider store={store}>
<ReactReduxFirebaseProvider {...rrfConfig}>
...
</ReactReduxFirebaseProvider>
</Provider>
);
The State
The tracing results
Each time when I click the button, the dispatch run twice, like the picture above.
This is the AppBar component and mapDispatchToProps function.
const mapStateToProps = state => {
return {
title: state.title
};
};
const mapDispatchToProps = {
onClick: () => {
return {
type: "TOGGLE_SIDEBAR"
};
}
};
const AppBar = props => (
<Box>
<Button icon={<Notification />} onClick={props.onClick} />
</Box>
);
const AppBatContainer = connect(
mapStateToProps,
mapDispatchToProps
)(AppBar);
export default AppBatContainer;
This is the reducer
import {
TOGGLE_SIDEBAR
} from "../constants/action-types";
const initialState = {
showBar: false
};
const rootReducer = (state = initialState, action) => {
switch (action.type) {
case TOGGLE_SIDEBAR:
return Object.assign({}, state, {
showBar: !state.showBar
});
default:
return state;
}
};
export default rootReducer;
This is the store.js
import { createStore, applyMiddleware, compose } from "redux";
import reduxThunk from "redux-thunk";
import rootReducer from "./reducers/index";
const composeEnhancers =
typeof window === "object" && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
// Specify extension’s options like name, actionsBlacklist, actionsCreators, serialize...
trace: true,
traceLimit: 20
})
: compose;
const enhancer = composeEnhancers(applyMiddleware(reduxThunk));
const store = createStore(rootReducer, enhancer);
export default store;
All libraries are well imported. I tried remove redux-thunk, it is still the same result.
Thanks in advance.
Ref
React-Redux Counter example action firing twice I have viewed this questions on stackoverflow, and tried the answers, but no of them solved it.