简体   繁体   中英

React Hot Loader: this component is not accepted by Hot Loader

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')
    );
  });
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM