2
votes

I am using https://github.com/stylesuxx/generator-react-webpack-redux for the generator and I am using hot-loader. My code is able to load normally in the browser but when I open the development panel in the browser, I encounter

React Hot Loader: this component is not accepted by Hot Loader. 
Please check is it extracted as a top level class, a function or a variable. 
Click below to reveal the source location: 
 ƒ (props, context, updater) {
      // This constructor gets overridden by mocks. The argument is used
      // by mocks to assert on what gets mounted.

      if (process.env.NODE_ENV !== 'production'… 

In my client.js, the code are shown below:

import React from 'react';
import ReactDOM from 'react-dom';
import { AppContainer } from 'react-hot-loader';
import { Provider } from 'react-redux';
import { Router, IndexRoute, Route, browserHistory, hashHistory } from 'react-router';
import App from './containers/App';
import configureStore from './stores';

import Contact from './containers/contact/Contact'
import Homepage from './containers/homepage/Homepage'
import About from './containers/about/About'
import Theme from './containers/themes/Themes'
import Login from './containers/login/Login'
import Signup from './containers/signup/Signup'

const store = configureStore();

const routes = {
  path: '/',
  indexRoute: {onEnter: (nextState, replace) => replace('/home')},
  childRoutes: [
    require('./containers/homepage').default,
    require('./containers/themes').default,
    require('./containers/contact').default,
    require('./containers/about').default,
    require('./containers/login').default,
    require('./containers/signup').default,
    {
      path: '*',
      indexRoute: { onEnter: (nextState, replace) => replace('/error/404') }
    }
  ]
}    

ReactDOM.render((
   <Provider store={store}>
    <Router onUpdate = {() => window.scrollTo(0, 0)}
      history={hashHistory}
      routes={routes}
    />
 </Provider>
 ), document.getElementById('app'));

// if (module.hot) {
//   module.hot.accept('./containers/App', () => {
//     const NextApp = require('./containers/App').default; // eslint-
 disable-line global-require
//
//     ReactDOM.render(
//       <AppContainer>
//         <Provider store={store}>
//           <NextApp />
//         </Provider>
//       </AppContainer>,
//       document.getElementById('app')
//     );
//   });
// }

How should I modify the commented code to make the Hot Loader to accept the component, I tried with code below and it doesn't work.

if (module.hot) {
  module.hot.accept('./containers/App', () => {
    const NextApp = require('./containers/App').default; // eslint-disable-line global-require

    ReactDOM.render(
      <AppContainer>
      <Provider store={store}>
        <Router onUpdate = {() => window.scrollTo(0, 0)}
          history={hashHistory}
          routes={routes}
        />
      </Provider>
      </AppContainer>,
      document.getElementById('app')
    );
  });
}
1
Did you make it work? :)Michal
No =( I have decided to ignore it at the momentMervyn Lee
Look at my repo. You will probably need to get rid of service workers. Other than that it is in almost perfect shape for your project. You can get back to this question later.Michal
I had excluded initializeServiceWorkers() but it still doesn't work. I try to console.log something in if (module.hot) logic but nothing is shown in the console =(Mervyn Lee
@Michal I appreciate your help. How can I find a better way to reach you ( in chat example) so we can solve this problem together fasterMervyn Lee

1 Answers

0
votes

I see a lot of code duplication. Instead of all the ReactDOM.render(( try creating function that renders the DOM for you.

Look at my example repo

First I create render function:

const render = () => {   ReactDOM.render(
    (
      <Provider store={store}>
        <BrowserRouter>
          {renderRoutes(routes)}
        </BrowserRouter>
      </Provider>
    ),
    document.getElementById('root'),   ) }

Then I render the app:

render()

Then I handle the hot reloading:

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

That could be also handled like this:

if (module.hot) {
   module.hot.accept('./app', () => {
     const UpdatedApp = require('./app').default // require('./app').default = renderRoutes(routes)
     render(UpdatedApp)
   })
 }

But my point is that you don't want to duplicate the render DOM code. When you extract the code and create dedicated function for rendering client side code. You will see the solution much clearer.

It will also help you handling server side rendering because you will be able to use the same function for rendering the code on server.