HMR for react-react-app with react-redux

时间:2017-02-13 21:37:46

标签: reactjs webpack redux react-router-redux webpack-hmr

对于使用create-react-app初始化的应用,未启用HMR。有一篇关于如何在此处启用它的博客文章:http://chrisshepherd.me/posts/adding-hot-module-reloading-to-create-react-app

ReactDOM.render(
  <App />,
  rootEl
);

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

我正在尝试做类似的事情,虽然我已将reduxreact-router-redux添加到混音中:

App.js

import React from 'react'
import { Provider } from 'react-redux'
import store from './store/store'
import routes from './routes'

const App = (
  <Provider store={store}>
    { routes }
  </Provider>
);

export default App;

routes.js

import React from 'react';
import { browserHistory, Router, Route } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
import store from '../store/store';
import { AnonymousLayout } from '../layouts';
import { LoginForm } from './Login';

const history = syncHistoryWithStore(browserHistory, store);

export default (
  <Router history={history}>
    <Route path="/" component={AnonymousLayout}>
      <Route path="/login" component={LoginForm} />
    </Route>
  </Router>
);

index.js

import React from 'react'
import ReactDOM from 'react-dom'
import App from './client/App';

const rootEl = document.getElementById('root');

ReactDOM.render(
  App,
  rootEl
);

if (module.hot) {
  module.hot.accept('./client/App', () => {
    const NextApp = './client/App';
    ReactDOM.render(
        <NextApp />,
        rootEl
      );
  });
}

但是,我刚收到此错误:

Warning: [react-router] You cannot change <Router routes>; it will be ignored

有没有办法攻击HMR进入这个项目?

4 个答案:

答案 0 :(得分:2)

Dan Abramov posted a solution适用于我的情况:

<强> index.js

// regular imports
ReactDOM.render(<App /> , document.getElementById('root'))

if (module.hot) {
  module.hot.accept('./App', () => {
    ReactDOM.render(<App />, document.getElementById('root'))
  })
}

<强> store.js

import { createStore } from 'redux'

import rootReducer from './reducers'

const configureStore = () => {
  const store = createStore(rootReducer)

  if (process.env.NODE_ENV !== "production") {
    if (module.hot) {
      module.hot.accept('./reducers', () => {
        store.replaceReducer(rootReducer)
      })
    }
  }

  return store
}

export default configureStore

答案 1 :(得分:1)

您需要导入AppContainer并用它包装NextApp容器。

import { AppContainer } from 'react-hot-loader';

...

...

if (module.hot) {
  module.hot.accept('./client/App', () => {
    const NextApp = './client/App';
    ReactDOM.render(
      <AppContainer />
        <NextApp />
      <AppContainer />,
        rootEl
      );
  });
}

您可能需要修改app.js,以便它包含道具

const App = (store, routes) => 
  <Provider store={store}>
    { routes }
  </Provider>;

然后对index.js中的商店和路线进行初始化,并将相同的storeroutes常量作为道具传递到<App /><NextApp />

我认为react-reouter-redux repo上的这个问题可以帮到你:

https://github.com/reactjs/react-router-redux/issues/179

答案 2 :(得分:0)

我能够使用Dan Abramov关于“migrating-from-create-react-app”https://github.com/gaearon/react-hot-loader#migrating-from-create-react-app的描述,我在Raspberry Pi(raspbian)上用流行的7英寸LCD触摸屏进行设置

为了增加额外的麻烦,我使用'netatalk'文件系统共享让Raspbian文件系统在OSX上显示为卷,这样我就可以在应用程序运行时在Macbook上的Atom编辑器中编辑应用程序源代码覆盆子。 当我在Atom中编辑源代码并保存文件时,应用程序将在Raspberry上重新编译,热模块替换将显示Raspberry LCD上的更改,而不会产生刷新效果。覆盆子不是最佳性能,所以改变发生需要几秒钟,但是很酷。

真正的向导可能会尝试进一步将源代码编译到Macbook(具有更多CPU能力)和编译代码的地方 仍然在Raspberry上运行和HMR更新。但是该方案在HMR意义上会如何看待?我不确定如何完成分区。

答案 3 :(得分:0)

我已经创建了一个样本仓库,它支持Redux的HMR。 使用create-react-app

对HMR进行React和Redux