rt2zz / redux-persist

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

<Provider> does not support changing `store` on the fly. #862

Open kodayashi opened 6 years ago

kodayashi commented 6 years ago

Redux-persist is working great, but I get the following error when trying to follow the HMR instructions:

does not support changing `store` on the fly. It is most likely that you see this error because you updated to Redux 2.x and React Redux 2.x which no longer hot reload reducers automatically. See https://github.com/reactjs/react-redux/releases/tag/v2.0.0 for the migration instructions.

Index.js:

import AppReducer from './app/reducers';

const loggerMiddleware = createLogger({
  predicate: (getState, action) => __DEV__,
});

const sagaMiddleware = createSagaMiddleware();

const persistConfig = {
  key: 'root',
  storage,
  whitelist: [
    'some-state',
    'some-other-state',
  ],
};

const persistedReducer = persistReducer(persistConfig, AppReducer);

const store = createStore(
  persistedReducer,
  compose(
    appStateMiddleware,
    applyMiddleware(
      loggerMiddleware,
      reactNavigationReduxMiddleware,
      sagaMiddleware,
    )
  )
);

const persistor = persistStore(store);

if (module.hot) {
  module.hot.accept(() => {
    // This fetch the new state of the above reducers.
    store.replaceReducer(
      persistReducer(persistConfig, AppReducer)
    )
  })
}

sagaMiddleware.run(AppSagas);

class MyApp extends Component {
  render() {
    return (
      <Provider store={store}>
        <PersistGate loading={null} persistor={persistor}>
          <App/>
        </PersistGate>
      </Provider>
    );
  }
}

AppRegistry.registerComponent('MyApp', () => MyApp);

export default MyApp;

Here is ./app/reducers/index.js:

import { combineReducers } from 'redux';

import * as someReducers from './some';
import * as someMoreReducers from './someMore';
import * as evenMoreReducers from './evenMore';

const AppReducer = combineReducers(Object.assign(
  someReducers,
  someMoreReducers,
  evenMoreReducers,
));

export default AppReducer;

Any idea what might be the issue here? I can't seem to find anyone else having this issue when searching older (closed) issues.

jqn commented 6 years ago

Any traction on this. I'm not finding any answers anywhere

mattlubner commented 5 years ago

I'm seeing the same thing, were you able to resolve this?

I'm on webpack@4.12.0 and think it's probably because module.hot.accept() accepts an error-handling callback when no dependencies are specified (according to their docs: https://webpack.js.org/api/hot-module-replacement/#accept-self-). I'm not sure, but maybe this is a behavioral change from webpack v3?

mattlubner commented 5 years ago

I was able to work past my issue. For anyone else that happens to find this thread, here's the fix:

  module.hot.accept('./app/reducers', () => {
    const nextAppReducer = require('./app/reducers').default;
    store.replaceReducer(
      persistReducer(persistConfig, nextAppReducer)
    );
  });