'Data is losing during page refresh in Reactjs-Redux; Tried using 'redux-persist' and localstorage , but not working
In our project,forms(login,signup,logout,etc..) were built in django and through this we are getting the authorization details and this was stored as redux-data and was used in the rest of the application which is built in react.There was no refresh issue during that time.evenif the store was getting disapper but we are getting it back.Now,we shifted all that we done in Django into react and used the same redux storage method in login,but we are facing the data losage during refresh,store is not getting restore and we are having 403 status for 2 apis for getting the user details.This was not happening in former case. We used redux-persist package to avoid this data losage.. And also tried using localstorage persisting method(loadState(),saveState()).But,still facing the issue.
store.js
import { createStore, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import rootReducer from './reducers'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage';
const persistConfig = {
key: "root",
storage,
}
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const persistedReducer = persistReducer(persistConfig,rootReducer)
const store = createStore(persistedReducer,composeEnhancers(applyMiddleware(thunk)))
const Persistor = persistStore(store);
export default (store)
export { Persistor }
action.js:
import axios from 'axios'
import { SET_PROFILE, SET_FEATURE_TOGGLES } from './actionTypes'
import { client_request_data } from '../config';
const redirectToLogin = () => {
delete axios.defaults.headers.common.Authorization
if (window.location.href.indexOf('/accounts/') !== -1) {
window.location.href = '/accounts/login'
}
}
export const fetchUserProfile = () => dispatch => {
axios
.post(`/accounts/user_profile/`,{
client_request_data: client_request_data
})
.then(resp =>
dispatch({
type: SET_PROFILE,
payload: resp.data,
}),
)
.catch(e => {
// TODO figure out what do do here
if (e.response?.status === 403) {
redirectToLogin()
}
})
}
export const fetchFeatureToggles = () => dispatch => {
axios
.post(`/api/study/v1/feature_toggle/`,{
client_request_data: client_request_data
})
.then(resp =>
dispatch({
type: SET_FEATURE_TOGGLES,
payload: resp.data,
}),
)
.catch(e => {
// TODO figure out what do do here
if (e.response?.status === 403) {
redirectToLogin()
}
})
}
Reducers:1.featureToggle.js
import { SET_FEATURE_TOGGLES } from '../actionTypes'
const intialstate = {}
export default (state = intialstate, action) => {
switch (action.type) {
case SET_FEATURE_TOGGLES:
return action.payload
default:
return state
}
}
2.userprofile.js
import { SET_PROFILE } from '../actionTypes'
const intialstate = {}
export default (state = {}, action) => {
switch (action.type) {
case SET_PROFILE:
return action.payload
default:
return state
}
}
App.js:
import React, { useEffect, Suspense } from 'react'
import { connect } from 'react-redux'
import CssBaseline from '@material-ui/core/CssBaseline'
import { ThemeProvider } from '@material-ui/styles'
import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider'
import { Provider } from 'react-redux'
import { BrowserRouter, Switch, Route } from 'react-router-dom'
import theme from './theme/muiTheme'
import './i18n'
import Home from './screens/Home'
import * as actions from './redux/actions'
import Userservice from './services/UserService'
import { BASE_URL} from './config'
import Login from './Login'
import Signup from './Signup'
import Logout from './Logout'
import ResetPassword from './ResetPassword'
import ResetSuccess from './ResetSuccess'
import store from './redux/store'
const App = props => {
const {
userProfile,
featureToggles,
fetchUserProfile,
fetchFeatureToggles,
} = props
useEffect(() => {
fetchUserProfile()
fetchFeatureToggles()
})
return (
<Suspense fallback={<span></span>}>
<BrowserRouter>
<Switch>
<Route
exact
path="/"
render={() => {
return (
userProfile === null || featureToggles === null ? <Login/> : <Home />
)
}}
/>
</Switch>
</BrowserRouter>
</Suspense>
)
}
const mapStateToProps = state => ({
userProfile: state.userProfile,
featureToggles: state.featureToggles,
})
export default connect(mapStateToProps, actions)(App)
index.js:
import promiseFinally from 'promise.prototype.finally'
import React, {Suspense} from 'react'
import ReactDOM from 'react-dom'
import './index.css'
import CssBaseline from '@material-ui/core/CssBaseline'
import { ThemeProvider } from '@material-ui/styles'
import MuiThemeProvider from '@material-ui/core/styles/MuiThemeProvider'
import { Provider } from 'react-redux'
import * as serviceWorker from './serviceWorker'
import App from './App'
import theme from './theme/muiTheme'
import store,{Persistor} from './redux/store'
import './i18n';
import Home from './screens/Home'
import Login from './Login'
import Signup from './Signup'
import Logout from './Logout'
import { PersistGate } from 'redux-persist/integration/react'
promiseFinally.shim()
ReactDOM.render(
<Provider store={store}>
<PersistGate Loading={null} persistor={Persistor}>
<MuiThemeProvider theme={theme}>
<ThemeProvider theme={theme}>
<CssBaseline />
<Suspense>
<App />
</Suspense>
</ThemeProvider>
</MuiThemeProvider>
</PersistGate>
</Provider>,
document.getElementById('root'),
)
serviceWorker.unregister()
Also tried with localstorage: localstorage.js(in redux)
export const loadState = () => {
try {
const serializedState = localStorage.getItem("state");
if (serializedState === null) {
return undefined;
}
return JSON.parse(serializedState);
} catch (err) {
return undefined;
}
};
export const saveState = (state) => {
try {
const serializesState = JSON.stringify(state);
localStorage.setItem("state", serializesState);
} catch (err) {
console.log(err);
}
};
Corresponding store.js:
import { createStore, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'
import rootReducer from './reducers'
import { persistStore,persistReducer} from 'redux-persist'
import storage from 'redux-persist/lib/storage';
import { fetchFeatureToggles } from './actions';
import { loadState,saveState } from './localStorage';
import { throttle } from 'lodash';
const persistConfig = {
key: "root",
storage,
}
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
const persistedState = loadState();
const persistedReducer = persistReducer(persistConfig,rootReducer)
const store = createStore(persistedReducer,persistedState,composeEnhancers(applyMiddleware(thunk)))
store.subscribe(throttle(() => {
saveState(store.getState());
},1000));
const Persistor = persistStore(store);
export default store
export {Persistor}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|