Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reducer not hotloading #44

Closed
emilchacko opened this issue Jul 23, 2015 · 24 comments
Closed

Reducer not hotloading #44

emilchacko opened this issue Jul 23, 2015 · 24 comments

Comments

@emilchacko
Copy link

case COUNTER_INCREMENT:
let {count} = state;
return {
count: count +1
};

changed it to

case COUNTER_INCREMENT:
let {count} = state;
return {
count: count +10
};

I'm getting the console log as:

[1] [piping] File src/reducers/counter.js has changed, reloading.
[0] Hash: 9bc9239a8a2f86a42fe5
[0] Version: webpack 1.10.3
[0] Time: 215ms
[0] Asset Size Chunks Chunk Names
[0] main-9bc9239a8a2f86a42fe5.js 3.02 MB 0 [emitted] main
[0] 0.4416de2fe6fb28b0fffb.hot-update.js 3.02 kB 0 [emitted] main
[0] 4416de2fe6fb28b0fffb.hot-update.json 36 bytes [emitted]

but it doesn't get reflected when I try to increment it using the button .What am I missing ?

@erikras
Copy link
Owner

erikras commented Jul 23, 2015

There's a discussion going on about this over on redux-devtools#24 and I've been working on it (unsuccessfully) on the reducer-reload-test branch. Any testing or debugging time you could put into it would be appreciated.

@erikras
Copy link
Owner

erikras commented Aug 8, 2015

I haven't gone back to work on this. It doesn't affect me that much. It should be pretty easy to suss out for @gaearon, but he's so busy with the 1.0 docs.

@gaearon
Copy link
Contributor

gaearon commented Aug 8, 2015

Ping me in a week or so?

@erikras
Copy link
Owner

erikras commented Aug 8, 2015

Will do. I just had a head scratching moment caused by my reducer not hot reloading, so I retract my previous "this doesn't affect me" statement. 😄

@erikras
Copy link
Owner

erikras commented Aug 17, 2015

🔈 Ping!

@timdorr
Copy link

timdorr commented Aug 17, 2015

So, the issue is with where the store is created, right? Why not create the store within the router file, rather than passing it in? You would pass in the initial state, not a fully composed store object, as the 3rd parameter.

If you need the store back outside of the router (which it looks like you do for the dev tools and SSR), include it in the resolve().

@northerneyes
Copy link

Based on todomvc example in redux-devtools I figured out that Hotloading for reducers stop working after we just add this line import * as reducers from './reducers'; to index.js file.

@romabelka
Copy link

Unfortunately it's not so easy. As @gaearon said, file that create store must:

  • has no side effects
  • exports the root React component

Just moving store creation logic won't help - we still exporting Promise, not the root React component

@northerneyes
Copy link

Yeah, there is problem to create stores inside the Root React component, when we are using react-router, for example.

@romabelka
Copy link

More over for my App, that was created from scratch, I implemented all 3 points from @gaearon, but it didn't help. So I'll wait for docs with universal react-router

@josebalius
Copy link

@gaearon pinging again! :p any chance you can give us a hand here?

@gaearon
Copy link
Contributor

gaearon commented Aug 18, 2015

Which branch should I try?

@northerneyes
Copy link

As I said, just add this line import * as reducers from './reducers'; to index.js file in your todomvc example in redux-devtools, and reducers hot reloading stop working. And need to reload server after that

@erikras
Copy link
Owner

erikras commented Aug 18, 2015

@gaearon This is the branch where I tried to get it working, but you could start fresh from master, too.

@gaearon
Copy link
Contributor

gaearon commented Aug 18, 2015

@erikras Getting this on master:

ROUTER ERROR:   TypeError: Cannot convert undefined or null to object

  - Function.keys

  - Html.js:40 Html.render
    /Users/dan/p/react-redux-universal-hot-example/src/Html.js:40:19

  - ReactCompositeComponent.js:789 [object Object].ReactCompositeComponentMixin.    _renderValidatedComponentWithoutOwnerOrContext
    [react-redux-universal-hot-example]/[react]/lib/ReactCompositeComponent.js:7    89:34

@gaearon
Copy link
Contributor

gaearon commented Aug 18, 2015

As I said, just add this line import * as reducers from './reducers'; to index.js file in your todomvc example in redux-devtools, and reducers hot reloading stop working.

That's the expected behavior. :-)

@erikras
Copy link
Owner

erikras commented Aug 18, 2015

@gaearon Very strange. I just blew away my webpack-stats.json, node_modules, ran npm install, and master is working for me with npm run dev.

@gaearon
Copy link
Contributor

gaearon commented Aug 18, 2015

Eh, I ran npm start. :-P Yeah I can run it now. Will investigate.

@gaearon
Copy link
Contributor

gaearon commented Aug 18, 2015

The simplest fix is to use Webpack's HMR API directly:

/* global __DEVELOPMENT__, __CLIENT__, __DEVTOOLS__ */
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import createMiddleware from './clientMiddleware';
import * as reducers from '../reducers/index';

let reducer = combineReducers(reducers);
let lastCreatedStore; // <------------------------------- remember store

if (module.hot) {
  module.hot.accept('../reducers/index', () => {
    reducer = combineReducers(require('../reducers/index'));
    lastCreatedStore.replaceReducer(reducer);
  });
}

export default function(client, data) {
  const middleware = createMiddleware(client);
  let finalCreateStore;
  if (__DEVELOPMENT__ && __CLIENT__ && __DEVTOOLS__) {
    const { devTools, persistState } = require('redux-devtools');
    finalCreateStore = compose(
      applyMiddleware(middleware),
      devTools(),
      persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/)),
      createStore
    );
  } else {
    finalCreateStore = applyMiddleware(middleware)(createStore);
  }
  const store = finalCreateStore(reducer, data);
  store.client = client;
  lastCreatedStore = store; // <------------------ remember store
  return store;
}

We'll have a better fix later, but you can use this for now.

@erikras
Copy link
Owner

erikras commented Aug 18, 2015

Awesome, @gaearon!!! I knew it'd be a matter of minutes for you. 😄

@northerneyes
Copy link

Work like a charm, huge thanks!

@gaearon
Copy link
Contributor

gaearon commented Aug 18, 2015

Simpler way to write the same thing:

/* global __DEVELOPMENT__, __CLIENT__, __DEVTOOLS__ */
import { createStore, combineReducers, applyMiddleware, compose } from 'redux';
import createMiddleware from './clientMiddleware';

export default function(client, data) {
  const middleware = createMiddleware(client);
  let finalCreateStore;
  if (__DEVELOPMENT__ && __CLIENT__ && __DEVTOOLS__) {
    const { devTools, persistState } = require('redux-devtools');
    finalCreateStore = compose(
      applyMiddleware(middleware),
      devTools(),
      persistState(window.location.href.match(/[?&]debug_session=([^&]+)\b/)),
      createStore
    );
  } else {
    finalCreateStore = applyMiddleware(middleware)(createStore);
  }

  const reducer = combineReducers(require('../reducers/index'));
  const store = finalCreateStore(reducer, data);
  store.client = client;

  if (module.hot) {
    module.hot.accept('../reducers/index', () => {
      const nextReducer = combineReducers(require('../reducers/index'));
      store.replaceReducer(nextReducer);
    });
  }

  return store;
}

Note that module.hot.accept is mutative and calling it many times replaces the hot update handler. This means that hot replacement will only work for the store you create() last. But in Redux you should have one store anyway, so not a problem.

@josebalius
Copy link

@gaearon @erikras thank you guys

@gaearon
Copy link
Contributor

gaearon commented Aug 18, 2015

No problem, sorry it took me so long to come back to this.

erikras pushed a commit that referenced this issue Aug 18, 2015
erikras pushed a commit that referenced this issue Aug 20, 2015
* master: (53 commits)
  upgraded redux-form to 0.2.1
  thunkified clientMiddleware to fix #103. action creators can now return (dispatch,getState)=>action now
  fixed children prop type
  conformed to new stricter linting guidelines
  oops. fixed typo introduce when fixing #127
  named function that create.js exports to fix #127
  updated deps.
  updated dev dependencies
  linting
  reworked survey to demonstrate capabilities of redux-form v0.2.0
  made minLength and maxLength errors make more sense
  Correct validation text for minLength
  simplified change made that fixed #44
  fixed hot reducer loading with @gaearon's help. fixes #44
  fixed typo in comment
  removed old leftover meta tag and title tag
  minor formatting issue
  fixed test. not sure what calling .to.be.ok accomplishes, but...
  added path
  linting
  ...

Conflicts:
	package.json
	src/views/Widgets.js
	src/views/createRoutes.js
erikras pushed a commit that referenced this issue Aug 21, 2015
* master:
  implemented inline widget editing with redux-form 0.2.4
  added a more in-your-face header to client.js
  fixed handling of query string in client bootstrap; added query parameter to universalRouter fetchData callbacks
  upgraded redux-form to 0.2.1
  thunkified clientMiddleware to fix #103. action creators can now return (dispatch,getState)=>action now
  fixed children prop type
  conformed to new stricter linting guidelines
  oops. fixed typo introduce when fixing #127
  named function that create.js exports to fix #127
  updated deps.
  updated dev dependencies
  linting
  reworked survey to demonstrate capabilities of redux-form v0.2.0
  made minLength and maxLength errors make more sense
  Correct validation text for minLength
  simplified change made that fixed #44
  fixed hot reducer loading with @gaearon's help. fixes #44
  fixed typo in comment
  removed old leftover meta tag and title tag
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants