rt2zz / redux-persist

persist and rehydrate a redux store
MIT License
12.91k stars 863 forks source link

react-boilerplate integration #581

Open thecodingwhale opened 6 years ago

thecodingwhale commented 6 years ago

I'm currently using https://github.com/react-boilerplate/react-boilerplate and I'm just wonder if anyone integrate redux-persist with it?

rt2zz commented 6 years ago

It should integrate easily per the instructions in the readme

mouthzipper commented 6 years ago

Integration with react-boilerplate: 1: edit reducers.js something like this:

import { persistCombineReducers } from 'redux-persist';
import session from 'redux-persist/lib/storage/session';
const config = {
  key: 'root',
  storage: session,
};
export default function createReducer(injectedReducers) {
  return persistCombineReducers(config, {
    route: routeReducer,
    global: globalReducer,
    language: languageProviderReducer,
    ...injectedReducers,
  });
}

2: edit configureStore.js something like this:

import { persistStore } from 'redux-persist';
const persistor = persistStore(store);
return { persistor, store };

3: edit app.js

import { PersistGate } from 'redux-persist/es/integration/react';
const { persistor, store } = configureStore(initialState, history);
const render = (messages) => {
 ReactDOM.render(
    <Provider store={store}>
      <PersistGate persistor={persistor}>
        <LanguageProvider messages={messages}>
          <ConnectedRouter history={history}>
            <App />
          </ConnectedRouter>
        </LanguageProvider>
      </PersistGate>
    </Provider>,
    MOUNT_NODE
 );
};
absqueued commented 6 years ago

@mouthzipper I followed exact steps above, here is the problem I ran into:

image

mouthzipper commented 6 years ago

@shekhardesigner I forgot to mention that I'm using v4.10.2, I think my solution won't work on the new version anymore. Need to check the docs in migrating to v5.X

billgo commented 6 years ago

@shekhardesigner How do you solve this problem?

absqueued commented 6 years ago

@billgo Haven't tried this yet!

absqueued commented 6 years ago

@mouthzipper You sure about the version you were using? 4.10.2 doesn't have session lib or PersistGate

mouthzipper commented 6 years ago

@shekhardesigner you are correct, if you decided to use 4.10.2 -- add/edit below codes in configureStore.js

import { persistStore, autoRehydrate } from 'redux-persist';
...
  const enhancers = [
    applyMiddleware(...middlewares),
    autoRehydrate(),
  ];
....
  persistStore(store);
 return store;
absqueued commented 6 years ago

I have been trying to integrate V5 of this redux-persist 5.9.1 with react boilerplate 3.4.0.

Here is what I have done so far:

1. Install NPM

npm i -S redux-persist redux-persist-transform-immutable

package.json

    "redux-persist": "^5.9.1",
    "redux-persist-transform-immutable": "^5.0.0",

2. Setup Redux Persist in store.js

//store.js
import .... (other usual stuff)
import { persistStore, persistReducer  } from 'redux-persist';
import storageSession from 'redux-persist/lib/storage/session';
import immutableTransform from 'redux-persist-transform-immutable';

const persistConfig = {
  transforms: [immutableTransform()],
  key: 'root',
  storage: storageSession,
}

const rootReducers = createReducer();

// Using persistReducer not persistCombineReducer because the rootReducer is already returned by combinedReducer from redux-immutable.
const persistedReducer = persistReducer (persistConfig, rootReducers)

export default function configureStore (initialState = {}, history) {
   // other usual stuffs ... 

   // I modified how store is created using persistedReducer

   const store = createStore(
      persistedReducer, // this line used to use createReducer() method
      fromJS(initialState),
      composeEnhancers(...enhancers),
   );

   const persistor = persistStore(store);

   return { persistor, store };

   // Please note, I have commented out hot reloading of reducers for now.
}

3. No change in reducers.js

4. Update App.js

import 'babel-polyfill';
import React from 'react';

// Added below
import { PersistGate } from 'redux-persist/es/integration/react';

// other usual setup

// Line below used to define just store but now we are defining persistor and store
const { persistor, store } = configureStore(initialState, browserHistory);

// Finally, update the render method:

const render = () => {
  ReactDOM.render(
    <Provider store={store}>
      <PersistGate persistor={persistor}>
        <Router
          history={history}
          routes={rootRoute}
          render={
            applyRouterMiddleware(useScroll())
          }
        />
      </PersistGate>
    </Provider>,
    document.getElementById('app')
  );
};

And still no luck:

Error:

image

I think I do not have immutable maps configured right. Any help?

JonathanLehner commented 6 years ago

:(

tilakgajjar commented 6 years ago

@shekhardesigner have you find any solution? I am having the same issue, please help if you have solved this issue. Thanks in advance.

JonathanLehner commented 6 years ago

I couldn't find a solution. However, I realised redux persist might not be necessary (better do not rely on something with so little documentation). On egghead.io there is an example of Dan Abramov. You can just subscribe to the store and use lodash throttle to save to local storage.

absqueued commented 6 years ago

@tilakz Take a look at this - https://github.com/hendrathings/react-boilerplate-redux-persist-sample

JonathanLehner commented 6 years ago

I mean here are literally 234 open issues.. https://egghead.io/lessons/javascript-redux-persisting-the-state-to-the-local-storage it takes like 5 minutes to setup. Redux persist is a nightmare of complexity and lacks documentation, so if it is not really crucial to save the whole state you might save a lot of time with subscribe.

absqueued commented 6 years ago

I agree with @JonathanLehner here, I too didn't implement redux-persist. Classic way of sessionStorage helped me do a custom implementation

tilakgajjar commented 6 years ago

@shekhardesigner @JonathanLehner Thanks guys for your help, the example of Dan Abramov worked out for me.

panchicore commented 5 years ago

localStorage.js

export const loadState = () => {
  try {
    const serializedState = localStorage.getItem('state')
    if (serializedState === null) {
      return undefined
    }
    return JSON.parse(serializedState)
  } catch (e) {
    console.log('loadStorage error = ', e)
    return undefined
  }
}

export const saveState = (state) => {
  try {
    const serializedState = JSON.stringify(state)
    localStorage.setItem('state', serializedState)
  } catch (e) {
    console.log('saveState error = ', e)
  }
}

app.js

import {throttle} from 'lodash'
import {loadState, saveState} from './localStorage'

// Create redux store with history
const initialState = loadState()
const store = configureStore(initialState, history)
store.subscribe(throttle(() => {
  //saveState(store.getState()) store the complete state, but I just need the user object so:
  saveState({
    user: store.getState().get('user') // note I am using immutablejs
  })

}, 1000)) // don't persist on disk too often, once per second maybe...

works for me, no need of redux-persist

ygr1k commented 4 years ago

Maybe these links would be helpful: Issue: https://github.com/rt2zz/redux-persist/issues/1028 PR: https://github.com/rt2zz/redux-persist/pull/1047