【问题标题】:React-hot-loader is almost working, what am i doing wrong?React-hot-loader 几乎可以工作了,我做错了什么?
【发布时间】:2017-06-25 00:25:10
【问题描述】:

我已经设法让 webpack 流程正常工作,并且浏览器正在获得热更新。但由于某种原因,我无法理解模块的交换似乎无法正常工作......

这是我的 index.js:

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

import { syncHistoryWithStore, routerMiddleware } from 'react-router-redux';
import { createStore, applyMiddleware } from 'redux';
import { Provider } from 'react-redux';
import thunkMiddleware from 'redux-thunk';

import authenticationMiddleware from './middleware/authentication.js';
import messageMiddleware from './middleware/navigationMessage.js';
import apiMiddleware from './middleware/api.js';

import AppRouter from './router.jsx';

import RootReducer from './reducers/root-reducer.js';

let store = createStore(RootReducer, applyMiddleware(thunkMiddleware, apiMiddleware, messageMiddleware, authenticationMiddleware, routerMiddleware(browserHistory)));

const history = syncHistoryWithStore(browserHistory, store);

let rootElement = document.getElementById('app-root');
const hotRender = (CurrentAppRouter) =>
  ReactDOM.render(
    <AppContainer>
      <Provider store={store}>
        <CurrentAppRouter history={history} />
      </Provider>
    </AppContainer>,
    rootElement
  );

hotRender(AppRouter);

if (module.hot) {
  module.hot.accept('./router.jsx', () => {
    hotRender(AppRouter);
  });
}

Provider.childContextTypes = {
  store: React.PropTypes.object
};

我在 chrome 的控制台中得到了这个:

然而 html 并没有更新,即使我手动来回导航更改也不会通过,只有当我手动重新加载页面时我的更改才会出现。

我做错了什么?

更新:

我的依赖:

"devDependencies": {
    "babel-cli": "^6.18.0",
    "babel-core": "^6.22.1",
    "babel-loader": "^6.2.10",
    "babel-plugin-transform-object-rest-spread": "^6.20.2",
    "babel-plugin-transform-react-jsx": "^6.8.0",
    "babel-plugin-transform-runtime": "^6.15.0",
    "babel-preset-es2015": "^6.22.0",
    "babel-preset-react": "^6.22.0",
    "babel-preset-stage-2": "^6.22.0",
    "eslint": "^3.9.1",
    "eslint-plugin-react": "^6.6.0",
    "express": "^4.13.4",
    "gulp": "^3.9.1",
    "gulp-concat-css": "^2.3.0",
    "gulp-sass": "^2.3.2",
    "json-loader": "^0.5.4",
    "react-hot-loader": "^3.0.0-beta.6",
    "webpack": "^2.2.0",
    "webpack-dev-server": "^2.2.0"
  },
  "dependencies": {
    "babel-polyfill": "^6.16.0",
    "babel-runtime": "^6.18.0",
    "es6-promise": "^4.0.5",
    "isomorphic-fetch": "^2.2.1",
    "jwt-decode": "^2.1.0",
    "mobile-detect": "^1.3.3",
    "raven": "^1.1.1",
    "raven-js": "^3.9.1",
    "react": "^15.4.2",
    "react-bootstrap": "^0.30.6",
    "react-dom": "^15.4.2",
    "react-icons": "^2.2.1",
    "react-redux": "^4.4.5",
    "react-router": "^3.0.0",
    "react-router-bootstrap": "^0.23.1",
    "react-router-redux": "^4.0.7",
    "redux": "^3.6.0",
    "redux-thunk": "^2.1.0",
    "whatwg-fetch": "^2.0.1"
  }

【问题讨论】:

  • 你使用的是哪个版本的 react-hot-loader?
  • @JoshKelley:用我的依赖更新了我的问题。

标签: javascript reactjs react-router react-redux react-hot-loader


【解决方案1】:

虽然我远不是 react-hot-loader 方面的专家,但我能够通过以下示例使其正常工作 herehere

我的代码看起来像这样。

import Root from './containers/Root';
// Root has the <Provider><Router>...</Router></Provider> components

render(
  <AppContainer>
    <Root store={store} history={history}/>
  </AppContainer>,
  document.getElementById('app')
);

if (module.hot) {
  module.hot.accept('./containers/Root', () => {
    const Root = require('./containers/Root').default;
    render(
      <AppContainer>
        <Root store={store} history={history}/>
      </AppContainer>,
      document.getElementById('app')
    );
  });
}

与您的代码相比,最大的区别似乎是每当触发热重载时我都会重新requireing 根组件。我还在 react-router 上方配置了一层热重载。

我收到了与您的控制台中显示的相同的 react-router 警告,目前我只是忽略它;我的应用程序其余部分的热加载工作正常。

【讨论】:

  • 感谢您的回复,它启发了我尝试将问题最小化。最后的问题是我的 .bablerc 文件中没有 react-hot-loader/babel 插件。我花了一段时间才弄清楚,但现在它可以工作了:)
【解决方案2】:

将您的 module.accept 代码更改为

let render = () => {
    ReactDOM.render(
     <AppContainer>
       <Provider store={store}>
          <CurrentAppRouter history={history} />
       </Provider>
      </AppContainer>,
      rootElement
    )
} 

module.hot.accept('./router.jsx', () =>
  setImmediate(() => {
    ReactDOM.unmountComponentAtNode(rootElement)
    render()
  })
)

【讨论】:

  • 试过你的例子,唯一的区别是我添加了一个 render();在 module.hot.accept 之前,我们得到一个初始渲染。不幸的是,它没有用。结果相同。
  • 其实我还有一个解决方案——只用module.hot.accept(),不带任何参数,它会有所帮助(我实际上不知道在哪种情况下)。
猜你喜欢
  • 2016-11-29
  • 2018-04-30
  • 1970-01-01
  • 1970-01-01
  • 2021-08-05
  • 2018-07-29
  • 2016-02-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多