rt2zz / redux-persist

persist and rehydrate a redux store
MIT License
12.97k stars 867 forks source link

Accessing persistor in unconnected part of app? #349

Open FoxxMD opened 7 years ago

FoxxMD commented 7 years ago

In my app I call persistStore when initializing store for the first time

// store.js
export default function configureStore(initialState = {}, history) {
...
const store = createStore(
    createReducer(),
    fromJS(initialState),
    composeEnhancers(...enhancers) // includes autoRehydrate
  );

const persistor = persistStore(store, { storage: localForage, whitelist: ['auth', 'support'] }, (a, b) => {
     console.log('Redux-Persist loaded state');
   });
...
return store;
}
// app.js
...
const initialState = {};
const store = configureStore(initialState, browserHistory);
const history = syncHistoryWithStore(browserHistory, store, {
 selectLocationState: makeSelectLocationState(),
});
...
const render = (messages) => {
 ReactDOM.render(
   <Provider store={store}>
     <LocaleProvider locale={enUS}>
       <Router
         history={history}
         routes={createRoutes(store)}
         render={
            applyRouterMiddleware(useScroll())
          }
       />

     </LocaleProvider>
   </Provider>,
    document.getElementById('app')
  );
};

Because I need REHYDRATE to fire so I can get stored user auth info and skip login, etc.

If there is no user auth info (IE user is logged out) I would like to do something similar to https://github.com/rt2zz/redux-persist/issues/253 and call persistor.pause() if the user has not checked "remember me" when they login.

However in the documentation I don't see a clear way to access persistor after it's initially created. How can I do this? Does it require recreating my entire store using the current store as initial state? just so i can get another persistor?

Viral-Inc commented 7 years ago

I'm basically wondering the same thing / having a hard time ): edit: i used context.store and it worked

FoxxMD commented 7 years ago

@Viral-Inc can you expand on that please? Right now I'm setting the persistor as a global variable on window and it feels shameful.

Viral-Inc commented 7 years ago

@FoxxMD me using context is kind of shameful too, but, basically I declared store as a contextType on a Purge class component:

import React, {Component} from 'react'
import {persistStore} from 'redux-persist'
import './purge.css'
import PropTypes from 'prop-types'

class Purge extends Component {

  handleSubmit = (e) => {
    e.preventDefault();
    persistStore(this.context.store).purge()
  };

  render() {
    return (
      <div id="pur-d1a">
        <div id="pur-d2a">
          <form onSubmit={this.handleSubmit}>
            <input type="submit" value="purge"/>
          </form>
        </div>
      </div>
    )
  };
}

Purge.contextTypes = {
  store: PropTypes.object
};

export default Purge
hugows commented 7 years ago

Me too. Any tips?

rt2zz commented 7 years ago

couple of options:

  1. if your config is statically defined, you can use purgeStoredState as follows
    
    import { purgeStoredState } from 'redux-persist'
    import { persistConfig } from 'somewhere you defined it'

// ...

purgeStoredState(persistConfig)



2. expose persistor via context, much like react-redux does for store

I would recommend option 1 when possible