Open kumarpatel opened 6 years ago
Hey @kumarpatel.
I'd probably define it right below startup
const persistor = persistStore(store, null, startup)
Then update the calls to persistStore
to use that persistor
and add it to the exports. Then you can just import it from Rehydration
.
If you're interested this would be a welcome PR! 😄
@ryanlntn Still not quite sure how to pass down the persistor. Would this work?
// Rehydration.js
const updateReducers = (store: Object) => {
const reducerVersion = ReduxPersist.reducerVersion
const startup = () => store.dispatch(StartupActions.startup())
const persistor = persistStore(store, null, startup)
// Check to ensure latest reducer version
AsyncStorage.getItem('reducerVersion').then((localVersion) => {
if (localVersion !== reducerVersion) {
if (DebugConfig.useReactotron) {
console.tron.display({
name: 'PURGE',
value: {
'Old Version:': localVersion,
'New Version:': reducerVersion
},
preview: 'Reducer Version Change Detected',
important: true
})
}
// Purge store
AsyncStorage.setItem('reducerVersion', reducerVersion)
persistor.purge()
}
}).catch(() => {
AsyncStorage.setItem('reducerVersion', reducerVersion)
})
return persistor
}
// CreateStore.js
// configure persistStore and check reducer version number
let persistor
if (ReduxPersist.active) {
persistor = Rehydration.updateReducers(store)
}
// kick off root saga
let sagasManager = sagaMiddleware.run(rootSaga)
return {
store,
persistor,
sagasManager,
sagaMiddleware
}
// App.js
// create our store
const { persistor, store } = createStore()
class App extends Component {
render () {
return (
<Provider store={store}>
<PersistGate
persistor={persistor}>
<App />
</PersistGate>
</Provider>
)
}
}
@ryanlntn I tried your suggested solution as well. Still not sure how to pass down persistor object since AsyncStorage.getItem is a promise function.
@apparition47 That looks like it should work and is more or less what I had in mind. Have you tried it out?
@kumarpatel Take a look at @apparition47's code above. You'll have to return the persistor outside of the promise which should be fine as it's the same instance.
@ryanlntn Yup. tried out @apparition47 's code.
Changing ReduxPersist.reducerVersion doesn't seem to be purging.
nvm. Just realized that this purges persisted data. i.e. not my redux state. I'll try to fire off a redux action to clear my redux state.
@ryanlntn It seems to work in my app from what I can see. Wasn't sure if there was a more graceful way to return the persistor though. If not, I can put this through as a PR if you'd like.
@apparition47 I think you could move the persistor creation out into CreateStore.js
and then pass it into updateReducers
for the sake of purging. That would be a little clearer since updateReducers
doesn't really imply it's going to return a persistor.
just read redux-persist v5 docs a little more closely about purging state if reducerVersion doesn't match. Migrations is the suggested way. Which means, Rehydration is a file that I don't need anymore. I just get my persistor in CreateStore.js and pass it down to App.js.
I'm cool with having this issue closed. Thanks for your help.
This is all rather confusing. @apparition47 example code did not work for me. Could I trouble any one of you for a complete example? Thank you.
@Unforgiven-wanda You don't need Rehydration file anymore
In CreateStore.js,
import { persistStore } from "redux-persist";
...
const persistor = persistStore(store);
// return your store and persistor
return { store, persistor };
in App.js (see official doc)
import createStore from "../Redux";
import { PersistGate } from 'redux-persist/integration/react'
//retrieve your store & persistor
const { store, persistor } = createStore();
// ... normal setup, create store and persistor, import components etc.
const App = () => {
return (
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<RootComponent />
</PersistGate>
</Provider>
);
};
You can manually purge your store: persister.purge(). You'll just need to pass persistor object down as needed. Or using redux-persist migrations to add data migration logic for old state -> new state. This migration can be as complicated as migrating every piece of data from old state to new state or as simple as purging old state and starting from scratch for new state. All depends on your business need.
Hopefully this helps.
Hey, for everyone who wants to use the code from @kumarpatel above, you also need to change Redux/index.js
to
export default () => {
...
let { store, persistor, sagasManager, sagaMiddleware } = configureStore(
finalReducers,
rootSaga
);
...
return { store, persistor };
};
So, I've followed all of the examples here (thank you for that by the way) and I can see in Reactotron that I have an action of type:persist/REHYDRATE
and persist/PERSIST
firing when the app loads, but my whitelisted Redux state is only loading it's initialState.
Is there some other magic that I'm missing here? Do I need to call a special action
for loading state into redux-persist?
@kumarpatel you mentioned don't need the Rehydration file. where/when would i exactly use persister.purge()
to always grab the correct version of reducer.
@ryanlntn Still not quite sure how to pass down the persistor. Would this work?
// Rehydration.js const updateReducers = (store: Object) => { const reducerVersion = ReduxPersist.reducerVersion const startup = () => store.dispatch(StartupActions.startup()) const persistor = persistStore(store, null, startup) // Check to ensure latest reducer version AsyncStorage.getItem('reducerVersion').then((localVersion) => { if (localVersion !== reducerVersion) { if (DebugConfig.useReactotron) { console.tron.display({ name: 'PURGE', value: { 'Old Version:': localVersion, 'New Version:': reducerVersion }, preview: 'Reducer Version Change Detected', important: true }) } // Purge store AsyncStorage.setItem('reducerVersion', reducerVersion) persistor.purge() } }).catch(() => { AsyncStorage.setItem('reducerVersion', reducerVersion) }) return persistor }
// CreateStore.js // configure persistStore and check reducer version number let persistor if (ReduxPersist.active) { persistor = Rehydration.updateReducers(store) } // kick off root saga let sagasManager = sagaMiddleware.run(rootSaga) return { store, persistor, sagasManager, sagaMiddleware }
// App.js // create our store const { persistor, store } = createStore() class App extends Component { render () { return ( <Provider store={store}> <PersistGate persistor={persistor}> <App /> </PersistGate> </Provider> ) } }
persistor = Rehydration.updateReducers(store)
this is an async call so need to account for it. @apparition47 what did you end up doing?
've followed all of the examples here (thank you for that by the way) and I can see in Reactotron that I have an action of
type:persist/REHYDRATE
andpersist/PERSIST
firing when the app loads, but my whitelisted Redux state is only loading it's initialState.Is there some other magic that I'm missing here? Do I need to call a special
action
for loading state into redux-persist?
I am facing the same problem . Were you able to solve it ?
Generated boilerplate PizzaApp using ignite-cli v2.0.0
needs to become
How do I get access to persistor here? Seems to be generated in Rehydration.js
Any help would be appreciated.