React Redux Persist - javascript

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')
)

Related

Redux-persist is returning initial State instead of persisting

I have added redux-persist in my code and it isn't persisting the state, instead I am always getting the initial state.
Here's the code of my root-reducer
import { combineReducers } from "redux";
import { persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import userReducer from "./Users/user-reducer";
import cartReducer from "./Cart/cart-reducer";
const persistConfig = {
key: "root",
storage,
whitelist: ["cart"],
};
const rootReducer = combineReducers({
user: userReducer,
cart: cartReducer,
});
export default persistReducer(persistConfig, rootReducer);
and this is my store.js file
import { createStore, applyMiddleware } from "redux";
import logger from "redux-logger";
import rootReducer from "./root-reducer";
import { persistStore } from "redux-persist";
const middlewares = [logger];
export const store = createStore(rootReducer, applyMiddleware(...middlewares));
export const persistor = persistStore(store);
Here's my index.js file
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { BrowserRouter } from "react-router-dom";
import { Provider } from "react-redux";
import { store, persistor } from "./redux/Store";
import { PersistGate } from "redux-persist/integration/react";
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<BrowserRouter>
<PersistGate persistor={persistor}>
<App />
</PersistGate>
</BrowserRouter>
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
Whenever I am refreshing my page with the initial state, I am getting rehydrated: true but after firing some action I am getting rehydrated: false.
Check your reducer.js and make sure the bottom of the reducer in the file is
default:
return state;
and not
default:
return {
...state,
};```

Whenever I wrap my App with PersistGate it gives me "TypeError: users.map is not a function" in one component, otherwise it works fine

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

TypeError: Cannot read property 'subscribe' of undefined PersistGate.componentDidMount

Im adding Redux persist into my applcaition for local storage. I believe ive followed the implementation correctly and i keep getting the error:
Cannot read property 'subscribe' of undefined TypeError: PersistGate.componentDidMount
node_modules/redux-persist/es/integration/react.js:76
Here is my code.
store.js
import { createStore, applyMiddleware } from 'redux';
import { persistStore } from 'redux-persist';
import logger from 'redux-logger';
import rootReducer from './root.reducer';
const middlewares = [logger];
export const store = createStore(rootReducer, applyMiddleware(...middlewares));
export const persistor = persistStore(store);
export default { store, persistor };
root.reducer.js
import { combineReducers } from 'redux';
import { persistReducer } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import userReducer from './user/user.reducer';
import cartReducer from './cart/cart.reducer';
const persistConfig = {
key: 'root',
storage,
whitelist: ['cart']
}
const rootReducer = combineReducers({
user: userReducer,
cart: cartReducer
});
export default persistReducer(persistConfig, rootReducer);
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import {BrowserRouter} from 'react-router-dom';
import App from './App';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import Store from './redux/store';
ReactDOM.render(
<Provider store={Store.store}>
<BrowserRouter>
<PersistGate persistor={Store.persistor} />
<App />
<PersistGate/>
</BrowserRouter>
</Provider>,
document.getElementById('root')
);
Syntax was off in index.js PersisGate wrapper.
Correct syntax is
<PersistGate persistor={Store.persistor}>
<App />
</PersistGate>
you messing something which is:
import {store,persistor} from "./redux/store";
<Provider store = {store} >
<Router >
<PersistGate loading = {null} persistor = {persistor}>
<App />
</PersistGate>
</Router>
</Provider>
i hope this solution help somone

How do I store my state in localstorage in my Redux application?

I am trying to build a Trello clone using React and Redux.
Details of the application:
The application consists of 4 columns called TODO, DOING, DONE and REJECTED
I can add card to any of the 4 columns.
In the card I have just plain text.
The cards can be further moved into any of the columns using a package called react-beautiful-dnd.
There is also a delete button sticked to each card to delete the card which is added.
What I am trying to do?
I have a sample data which is first rendered when the application is first loaded.
The data is just demo, and contains id, text property for each and every card.
I want to use localstorage to add the card and further delete the card.
I want to use possibly Redux subscribe to achieve this.
I do not have much experience in dealing with Redux and localstorage altogether.
How can I do this?
Any help would be really appreciated and much required.
I have my codesandbox where I have my application running. Please consider checking out to help me out.
https://codesandbox.io/s/small-violet-zmbtf
You have to use redux persist
// configureStore.js
import { createStore } from 'redux'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage' // defaults to localStorage for web
import rootReducer from './reducers'
const persistConfig = {
key: 'root',
storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer)
export default () => {
let store = createStore(persistedReducer)
let persistor = persistStore(store)
return { store, persistor }
}
// App.js
import { PersistGate } from 'redux-persist/integration/react'
// ... normal setup, create store and persistor, import components etc.
const App = () => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RootComponent />
</PersistGate>
</Provider>
);
};
Edited check below:
change codesandbox to:
store/index.js:
// store/index.js:
import { createStore } from "redux";
import { persistStore } from "redux-persist";
import rootReducer from "../reducers";
export const store = createStore(rootReducer);
export const persistor = persistStore(store);
*******
reducers/index.js:
// reducers/index.js:
import { combineReducers } from "redux";
import { persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import listReducers from "./listReducers";
const persistConfig = {
key: "root",
storage,
whitelist: ["lists"]
};
export default persistReducer(persistConfig, combineReducers({
lists: listReducers
}));
root project index.js:
// index.js:
import React from "react";
import ReactDOM from "react-dom";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";
import { store, persistor } from "./store";
import "./styles/main.scss";
import App from "./components/App";
import * as serviceWorker from "./serviceWorker";
ReactDOM.render(
<Provider store={store}>
<PersistGate persistor={persistor}>
<App />
</PersistGate>
</Provider>,
document.getElementById("root")
);
serviceWorker.unregister();

Adding persistence to react redux immutable web app

I am trying to add persistence to my redux stores, I am using Immutable.js within my webapp. I have seen the following libraries: https://github.com/rt2zz/redux-persist and https://github.com/rt2zz/redux-persist-immutable I am wondering exactly how to create the persister and the store in context of my application, please see the following config-store.js:
import rootReducer from '../reducers'
import {
createStore,
compose,
applyMiddleware
} from 'redux'
import thunk from 'redux-thunk'
export default (initialState) => {
return createStore(
rootReducer,
initialState,
compose(
applyMiddleware(thunk),
window.devToolsExtension ? window.devToolsExtension() : f => f
)
);
};
and my index.js:
import React from 'react';
import {render} from 'react-dom';
import './index.css';
import App from './App';
import {Provider} from 'react-redux';
import configureStore from './store/configure-store';
import registerServiceWorker from './registerServiceWorker';
const store = configureStore();
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
)
registerServiceWorker();
Load the persiting state from local storage.
if (localStorage.getItem("state")) {
var serializedState = localStorage.getItem("state");
/* upload changes to server here */
preloadedState = JSON.parse(serializedState);
}
Save store changes to local storage.
store.subscribe(() => {
var serializedState = JSON.stringify(store.getState());
localStorage.setItem("state", serializedState);
});

Categories

Resources