React-hot-loader: Reloading entire tree vs changed component

Created on 7 Mar 2017  Â·  34Comments  Â·  Source: gaearon/react-hot-loader

If you are reporting a bug or having an issue setting up React Hot Loader, please fill in below. For feature requests, feel free to remove this template entirely.

Description

What you are reporting: reloads entire tree vs changed component

Expected behavior

What you think should happen: like prior version should only reload changed component

Actual behavior

What actually happens: reloads entire tree

as seen. when only when only EditorForm.js was changed

[WDS] App updated. Recompiling...
client:40 [WDS] App hot update...
only-dev-server.js:59 [HMR] Checking for updates on the server...
log-apply-result.js:20 [HMR] Updated modules:
log-apply-result.js:22 [HMR]  - ./app/availability/containers/EditorForm.js
log-apply-result.js:22 [HMR]  - ./app/availability/components/Editor.js
log-apply-result.js:22 [HMR]  - ./app/availability/index.js
log-apply-result.js:22 [HMR]  - ./app/routes.js
log-apply-result.js:22 [HMR]  - ./app/root.js
only-dev-server.js:40 [HMR] App is up to date.

Environment

React Hot Loader version:

Run these commands in the project folder and fill in their results:

  1. node -v: v6.9.3
  2. npm -v: v4.4.0

Then, specify:

  1. Operating system: OSX
  2. Browser and version: Chome Latest

Configs
https://gist.github.com/th3fallen/dc19cac7c09482ec5ed28e743d05ccd6

I feel like it's due to the router but in using the babel plugin i'd expect it know be able to sidestep that?

bug

Most helpful comment

All 34 comments

I have this exact same issue occurring currently - Although I'm not entirely sure that this is an issue.

Can you put the files from that Gist into a runnable project, like the issue template asks?

I think the behaviour is the entire path of components not the whole tree. If so I think I've got the same issue. All parent components up to the root are being renewed when a "leaf" component is updated for me.

wow i really dropped the ball on this one @calesce i'll "try" to get you a running version frist thing monday morning

I'm experiencing the same issue, though it's possible it's a configuration issue. I'm using Webpack's code splitting to split each route in the app, if that's pertinent.

@calesce Also seeing this issue... I'd love to get an answer here... I can upload an example if you need it, but it sounds like it is affecting multiple people.

Is this the intended behavior or not?

Same issue here, I have:
react-hot-loader": "3.0.0-beta.6"
in babel.js

...
"plugins": [
      "react-hot-loader/babel"
]
...

in webpack.config.js

...
'react-hot-loader/patch',
'webpack/hot/dev-server',
`webpack-hot-middleware/client?${root}`,
'entry.js'
...

in app.jsx

function renderApplication(RootComponent) {
    ReactDOM.render(
        <AppContainer>
        <Provider store={store}>
            <ConnectedRouter history={history}>
                <Route path="/" component={RootComponent} />
            </ConnectedRouter>
        </Provider>
        </AppContainer>,
        document.getElementById('app')
    );
}

if (module.hot) {
    module.hot.accept('./components/Root', () => {
        renderApplication(Root);
    });
}

Tree A -> B -> C
If I edit C, always the whole tree is updated and components are remounted, but redux state is kept and fine

After some investigation I found out that this works:

A is root component

export default injectIntl(A);

but this does not:

export default connect(rootSelector, dispatchToProps)(injectIntl(A));

this issue looks similar https://github.com/gaearon/react-hot-loader/issues/513

@vojty @gaearon What can i do to avoid this issue instead of compose?

Is <AppContainer> really needed?
Removing it solves the issue for me.

Looks like it's using:

      // Force-update the whole tree, including
      // components that refuse to update.
      deepForceUpdate(this);

I guess it was added to solve some edge cases.
But it's not logical that other components get re-rendered when we change only 1 component.

@alexilyaev hot reloading still works without the appcontainer in your project? mine fails to update anything?

It should not work without it. Cos updating sources will not cause redraw.

I'm also experiencing this issue. Is this intended behaviour?

@cjnaude - yes. If you do have module.accept only on App level - HRM(part of webpack, not RHL) will update a lot of modules down to the tree.
So having "[HMR]" in logs - it is ok.
Having a tree rerender is not ok, but there is no official way to debug and fix it.

Unfortunately, all "game masters" have left this place 👎

In-case this helps anyone:

My issue, as discovered by someone else in another thread, was that I was using React Router 3 with async routes. Moving to RR4 - sync, at least - appears to have solved it for me.

That could be solved by https://github.com/gaearon/react-hot-loader/pull/608, but no one review anything here for ages :(

I fixed my issue with the help of this link (look at the answer by Armour).

I had this code originally:

if (module.hot) {
  module.hot.accept();
}

which I then replaced with:

if (module.hot) {
  module.hot.accept("./components/Root", () => {
    const Next = require("./components/Root").default;
    render(<Next />);
  });
}

Works perfectly now!

@cjnaude - first - RFTM(always and carefully), next use webpack 3. By this time "before" variant of Amour's code is correct, and "workable" is obsolete.

@theKashey Apologies. I'm using .NET Core, and it seems half my problems are stemming from the fact that the hot module reloading is being configured using the "UseWebpackDevMiddleware" method of the IApplicationBuilder (no config in webpack itself). I've not been able to find much documentation on this, so I'm just happy to have something that works. But I completely agree with you, I need to update to webpack 3 and move over my HMR config. Apologies for posting an obsolete answer.

@th3fallen Actually it did not work, for some reason thought it did.
Can we help in a any way?
Some direction would be nice.

Did some more tests...
https://github.com/alexilyaev/react-es6-starter/tree/hmr-test (hmr-test branch)

Looks like I had the new ModuleConcatenationPlugin enabled and it screwed things up.
After commenting it out, things work as expected.

There's s counter in Root, changing some text in Hello does not re-render Root, only Hello.

Having the same problem. Have a vanilla setup from eject create-react-app and doing the minimum in the migration guide. Everytime I change a css class, the entire tree re-renders. Losing my mind over here :(

Ok, nightmare scenario related to HOC. I had written something a bit differently than I usually do...

// This anonymous example DOES NOT work with react-hot-loader
export const Component = connect(stateToProps)(class extends React.Component {
...
})

export default Component
// this example DOES work
class Component extends React.Component {
...
})

export default connect(stateToProps)(Component)

@jamesmfriedman - "expected" behaviour. All parts must be extracted as top level variables (visible to babel plugin). Or RHL will not understand how to replace a spare part.

@theKashey we should document it..

A little bit of documentation would’ve gone a long way for me. I found a few different posts about issues with HOC but they were more about why they were an issue and not how to avoid the problem.

For me, a few simple good and bad examples would have been super helpful!

Happy it’s working again. The 4 hours of troubleshooting has already been regained in time saved from RHL.

Sent from my iPhone

On Sep 21, 2017, at 6:38 AM, Greg Bergé notifications@github.com wrote:

@theKashey we should document it..

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

@neoziro any chance we can remove the unconfirmed tag on this since it's clear others have the same issues?

Since hmre is now dead in react-16 looks like I'll begrudgingly have to come back to this and just let my entire tree rerender :(

@th3fallen dead?

@theKashey it doesnt rerender components anymore after changes,

Also @neoziro thanks for removing that badge would you say this is a bug?

@th3fallen yeah I think so.

It was relative to React Router v3. If you are using React Router v3, please update to v4 if you want to use React Hot Loader.

I'm experiencing this issue (not using react router, any version). @neoziro Do we know what the underlying cause was?

@joshjg - some React components, invisible to ReactHotLoader - any decorators or any functional composition.
A technical solution was found, and the only things left - new tests and new documentation.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tiberiumaxim picture tiberiumaxim  Â·  4Comments

sandysaders picture sandysaders  Â·  4Comments

rockchalkwushock picture rockchalkwushock  Â·  3Comments

esturcke picture esturcke  Â·  3Comments

theKashey picture theKashey  Â·  3Comments