Redux-persist: autoRehydrate doesn't working with hot reloading

Created on 1 Feb 2017  路  9Comments  路  Source: rt2zz/redux-persist

Thank you for this great library, I'm using it with RN for building an iOS app. I have noticed that if I apply the autoRehydrate() method in my configureStore.js that the hot reloading of iOS simulator won't working, there's any suggestion for this or if I can just remove the autoRehydrate(), if I do this will the redux-persist sill workable?

Here's my configureStore.js :

/* @flow */

import { AsyncStorage } from 'react-native';
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'remote-redux-devtools';
import thunk from 'redux-thunk';
import { persistStore, autoRehydrate } from 'redux-persist';
import rootReducer from '../reducers';

export default (onComplete?: () => void): any => {
  const store = createStore(rootReducer, composeWithDevTools(
    applyMiddleware(thunk),
    autoRehydrate(),
  ));

  if (module.hot) {
    // $FlowFixMe
    module.hot.accept(() => {
      const nextRootReducer = require('../reducers').default;
      store.replaceReducer(nextRootReducer);
    });
  }

  persistStore(store, { storage: AsyncStorage }, onComplete);

  return store;
};
feature request stale v5

Most helpful comment

Not sure it is redux-devtools problem, but you can disable recomputing actions there by setting shouldHotReload to false:

const composeEnhancers = composeWithDevTools({ shouldHotReload: false });
  const store = createStore(rootReducer, composeEnhancers(
    applyMiddleware(thunk),
    autoRehydrate(),
  ));

See more details in the devtools API.

All 9 comments

Not sure it is redux-devtools problem, but you can disable recomputing actions there by setting shouldHotReload to false:

const composeEnhancers = composeWithDevTools({ shouldHotReload: false });
  const store = createStore(rootReducer, composeEnhancers(
    applyMiddleware(thunk),
    autoRehydrate(),
  ));

See more details in the devtools API.

@zalmoxisus I have tried to use the following types of code, the result is wired.

Type 1 : If I remove the autoRehydrate(), hot reloading can work

/* @flow */

import { AsyncStorage } from 'react-native';
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'remote-redux-devtools';
import thunk from 'redux-thunk';
import { persistStore, autoRehydrate } from 'redux-persist';
import rootReducer from '../reducers';

export default (onComplete?: () => void): any => {
  // const composeEnhancers = composeWithDevTools({ shouldHotReload: false });
  const store = createStore(rootReducer, composeWithDevTools(
    applyMiddleware(thunk),
    autoRehydrate(),
  ));

  if (module.hot) {
    // $FlowFixMe
    module.hot.accept(() => {
      const nextRootReducer = require('../reducers').default;
      store.replaceReducer(nextRootReducer);
    });
  }

  persistStore(store, { storage: AsyncStorage }, onComplete);

  return store;
};

Type 2 : Hot reloading totally can't work, even I remove the autoRehydrate(). And I press cmd + R the redux state won't be updated on iOS simulator

/* @flow */

import { AsyncStorage } from 'react-native';
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'remote-redux-devtools';
import thunk from 'redux-thunk';
import { persistStore, autoRehydrate } from 'redux-persist';
import rootReducer from '../reducers';

export default (onComplete?: () => void): any => {
  const composeEnhancers = composeWithDevTools({ shouldHotReload: false });
  const store = createStore(rootReducer, composeEnhancers(
    applyMiddleware(thunk),
    autoRehydrate(),
  ));

  if (module.hot) {
    // $FlowFixMe
    module.hot.accept(() => {
      const nextRootReducer = require('../reducers').default;
      store.replaceReducer(nextRootReducer);
    });
  }

  persistStore(store, { storage: AsyncStorage }, onComplete);

  return store;
};

Type 3 : Hot reloading can't work and I press cmd + R the redux state won't be updated on iOS simulator

/* @flow */

import { AsyncStorage } from 'react-native';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { persistStore, autoRehydrate } from 'redux-persist';
import rootReducer from '../reducers';

export default (onComplete?: () => void): any => {
  const store = createStore(rootReducer, applyMiddleware(thunk), autoRehydrate());

  if (module.hot) {
    // $FlowFixMe
    module.hot.accept(() => {
      const nextRootReducer = require('../reducers').default;
      store.replaceReducer(nextRootReducer);
    });
  }

  persistStore(store, { storage: AsyncStorage }, onComplete);

  return store;
};

Type 4 : Hot reloading can't work and I press cmd + R the redux state can be updated on iOS simulator

/* @flow */

import { AsyncStorage } from 'react-native';
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { persistStore } from 'redux-persist';
import rootReducer from '../reducers';

export default (onComplete?: () => void): any => {
  const store = createStore(rootReducer, applyMiddleware(thunk));

  if (module.hot) {
    // $FlowFixMe
    module.hot.accept(() => {
      const nextRootReducer = require('../reducers').default;
      store.replaceReducer(nextRootReducer);
    });
  }

  persistStore(store, { storage: AsyncStorage }, onComplete);

  return store;
};

I see. Then it's not Redux DevTools issue, seems like autoRehydrate overwrites the state after recomputing occurs.

Any suggestion for this issue?

@wellyshen I am not sure, in the past I have not enabled hot reload for reducers, only component tree. That said it should work, but I think may be complicated by the abstraction level that was chosen for autoRehydrate (a store enhancer). In reality a higher order reducer is sufficient and simpler.

Towards that effect, I would recommend you give https://github.com/rt2zz/redux-persist-state-manager a try. It is a higher order reducer which plays the same role as autoRehydrate and will soon be the recommended solution.

@rt2zz That looks awesome! Would it make sense to replace autoRehydrate with the solution in your new repo in the future?

@marvinhagemeister I think so but still some open questions:

  • is shallow merge (autoRehydrate) or hard set (stateManager) better? the latter is simpler, but may lead to more runtime errors due to accidentally missing values that were present in initialState but overwritten by REHYDRATE.
  • is the api around migrations correct? One thing that smells bad is the dictionary of string integer keys { '1': firstMigration, ... }.

Hopefully we can get some early adopters to help feel out the answers to these questions, and presumably move over to redux-persist core in v5.

I have this problem too !
When I'm using hot reload, my redux state is not save, any solution ?

This hasn't been responded to in a long while, so I'm going to mark it as stale. Please feel free to continue the conversation and I'll reopen.

Was this page helpful?
0 / 5 - 0 ratings