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

content doesn't reload #511

Closed
sylhero opened this issue Mar 9, 2017 · 14 comments
Closed

content doesn't reload #511

sylhero opened this issue Mar 9, 2017 · 14 comments
Labels

Comments

@sylhero
Copy link

sylhero commented Mar 9, 2017

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

HMR is working but content is not reloading
What you are reporting:
bug

Expected behavior

content gets reloaded
What you think should happen:

Actual behavior

What actually happens:

Environment

windows 8.1 npm 4.1.1 "webpack": "^2.2.0", "webpack-dev-server": "^2.4.1", "react-hot-loader": "^3.0.0-beta.6", "react-redux": "^4.4.6",
React Hot Loader version:
"react-hot-loader": "^3.0.0-beta.6"
Run these commands in the project folder and fill in their results:

  1. node -v: 6.9.4
  2. npm -v: 4.1.1

Then, specify:

  1. Operating system: windows 8.1
  2. Browser and version: chrome latest

Reproducible Demo

Please take the time to create a new project that reproduces the issue.
in the index.jsx

import React from 'react';
import { render } from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import { Router, browserHistory } from 'react-router';
import { Provider } from 'react-redux';
import Routes from './Routes';
import WidgetsApp from './App';
import WidgetsStore from './Store';
import './index.html';

const store = WidgetsStore.configureStore();
const rootElement = document.getElementById('root');
const appRender = (App) => {
    render(<AppContainer>
               <Provider store={ store }>
                   <App/>
               </Provider>
           </AppContainer>, rootElement);
};
appRender(WidgetsApp);

if (module.hot) {
    module.hot.accept('./App', () => {
        const WidgetsApp = require('./App').default;
        appRender(WidgetsApp);
    });
}

in .babelrc

{
  "presets": [
    ["es2015", {"loose" : true, "modules": false}],
    //Webpack understands the native import syntax, and uses it for tree shaking

    "stage-0",
    //Specifies what level of language features to activate.
    //State 2 is "draft", 4 is finished, 0 is strawman.
    //See https://tc39.github.io/process-document/

    "react"
    //Transpile React components to JS
  ],
  "env": {
    "test": {
      "plugins": [ "istanbul" ]
    }
  },
  "plugins": ['transform-runtime', 'transform-decorators-legacy', 'transform-class-properties', 'react-hot-loader/babel']
}

in webpack.config.js

entry: {
        app: [
            'babel-polyfill',
            'react-hot-loader/patch',
            './src/index.jsx'
        ],
        vendor: [
            './src/Vendor.jsx'
        ]

You can copy your project that experiences the problem and start removing things until you’re left with the minimal reproducible demo. This helps contributors, and you might get to the root of your problem during that process.

I think what cause the problem is the Provider if I don't use it it works fine

Push to GitHub and paste the link here.

@HeyHugo
Copy link

HeyHugo commented Mar 9, 2017

I'm experiencing the same problem.

I've got a project where components that has state injected from the store will not reload and the same goes for all child components to those components.

However components without store connection or ancestors reloads just fine.

Versions:

  • node 7.6.0
  • react-redux@5.0.3
  • redux@3.6.0
  • react-hot-loader@3.0.0-beta.6
  • webpack@2.2.1
  • webpack-dev-server@2.4.1

@HeyHugo
Copy link

HeyHugo commented Mar 23, 2017

I got this working now. There were two things I needed to change.
First I was wrapping the App component in with redux's <Provider> I moved it inside App instead.

and then I tried what someone suggested here webpack/webpack-dev-server#100 (comment)

..and re-imported the App component inside if (module.hot) {...}

Like this:

// Hot Module Replacement API
if (module.hot) {
  const NextApp = require('components/App').default;
  module.hot.accept('components/App', () => { render(NextApp) })
}

@wkwiatek
Copy link
Collaborator

@sylhero could you try to put <Provider> into the <App>? Also, full repo would really help here.

@sylhero
Copy link
Author

sylhero commented Mar 27, 2017

@wkwiatek thanks for replying me. I tried your suggestion but still not working. I can not provide a repo but it's easy to reproduce.

@sylhero
Copy link
Author

sylhero commented Mar 27, 2017

@HeyHugo thanks for the solution!

@chbinghu
Copy link

@HeyHugo Thank for the solution! It works well!

@yjkogan
Copy link

yjkogan commented Apr 2, 2017

I did not need to move the Provider into the app but re-importing directly inside the accept seemed to fix things. @HeyHugo it looks like you may have a typo doing the require before module.hot.accept? The issue you link to does the require inside, ala

if (module.hot) {
  module.hot.accept('./App', () => {
    const App = require('./App').default;
    render(App);
  });
}

I fought with this a long while, so for anyone else here's the basics of my setup for react / redux / react-router v4.

// index.js (the entrypoint for webpack)

require('../css/index.scss');
require.context('../images', true, /^\.\//);

import React from 'react';
import ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';

import { Provider } from 'react-redux';
import { compose, createStore } from 'redux';
import persistState from 'redux-localstorage';
import rootReducer from './state';


const enhancer = compose(
  persistState('settings'),
);

const initialState = undefined; // eslint-disable-line no-undefined

const store = createStore(rootReducer, initialState, enhancer);

import App from './App';

const rootEl = document.getElementById('Root');
// Render the main component into the dom
const render = (Component) => {
  ReactDOM.render(
    <AppContainer>
      <Provider store={store}>
        <Component />
      </Provider>
    </AppContainer>,
    rootEl
  );
};

render(App);

if (module.hot) {
  module.hot.accept('./App', () => {
    const App = require('./App').default;
    render(App);
  });
}
// App.jsx
import React from 'react';
import { BrowserRouter } from 'react-router-dom';

import NavigationRoute from 'routes/NavigationRoute';

// Render the main component into the dom
export default class App extends React.Component { //eslint-disable-line react/require-optimization
  render() {
    return (
      <BrowserRouter>
        <NavigationRoute />
      </BrowserRouter>
    );
  }
}
// NavigationRoute.jsx (simplified)

import React from 'react';
import { Redirect, Route, Switch } from 'react-router';

import Header from 'components/Header';

import EmergencyRoute from 'routes/EmergencyRoute';
import MapRoute from 'routes/MapRoute';
import MoreRoute from 'routes/MoreRoute';

class NavigationRoute extends React.Component {
  shouldComponentUpdate() {
    return true;
  }

  render() {
    return (
      <div className='NavigationRoute'>
        <Header />
        <div className='NavigationRoute-content'>
          <Switch>
            <Route path='/emergency' component={EmergencyRoute} />
            <Route path='/more' component={MoreRoute} />
            <Route path='/map' component={MapRoute} />
            <Redirect from='*' to='/map' />
          </Switch>
        </div>
      </div>
    );
  }
}

NavigationRoute.propTypes = {};

export default NavigationRoute;

@davecranwell
Copy link

I'm getting this too (see my mistakenly reported ticket here: webpack/webpack#4703)

Is this if(module.hot) thing the solution, or just a hack? Given that none of the webpack docs indicate this is necessary, they should at least be updated if so.

@Albert-Gao
Copy link

@HeyHugo Hi. Thanks for the solution. If you reimport that module, in if (module.hot), it works, but it seems that the page is doing a force reloading, and all the redux state gets lost. So you sure, in your case, it's an HMR rather than a page reload? Thanks :)

@qskane
Copy link

qskane commented Nov 9, 2017

@HeyHugo It is works for me , thanks

 const NextApp = require('components/App').default;
  module.hot.accept('components/App', () => { render(NextApp) })

BTW , when i use lazy loading , this is still not work for me

@eric-leihe
Copy link

For my case, it was caused by the .babelrc configuration. You need to config the babel to disable module transformation. I do the set as below:
{ "presets": [ ["env", { "modules": false }] ] }
Then the reload works well.

@theKashey
Copy link
Collaborator

Keep in mind - when you don't use harmony modules, ie not transpiled import/export, you have to re-require updated module by yourself.
When you will enable them (by disabling babel modules) as @ehe888 said - everything will work out of the box.

@gregberge
Copy link
Collaborator

The two modes (harmony and cjs) are now supported with new hot setup. React Hot Loader v4 is ready to be tested! Give it a try!

@lucksp
Copy link

lucksp commented Feb 7, 2018

@ehe888 your comment solved my issue of my Home component not updating in the DOM/reloading the updated file into sources. The HMR console logging says "successful" but it never updated since source file was not being refreshed.

Can you explain this more? i am new to Webpack & babel configs. This is my updated .babelrc file:

{
  "presets": [["env", { "modules": false }], "react", "stage-1"],
  "plugins": ["react-hot-loader/babel"]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests