使用Redux反应热重载

Jac*_*ack 5 reactjs redux react-hot-loader webpack-hmr react-redux

我已经使用HMR / React Hot Reloader进行了所有工作,因为它与视图有关。但是在添加了redux,react-redux等之后,每当我修改视图或化简器时,都会出现以下错误:

<Provider> does not support changing `store` on the fly. It is most likely that you see this error because you updated to Redux 2.x and React Redux 2.x which no longer hot reload reducers automatically. See https://github.com/reactjs/react-redux/releases/tag/v2.0.0 for the migration instructions.

遵循错误中的链接会导致有2年的历史,关于明确使用replaceReducer的帖子,这就是我所做的。

我的版本:

“ redux”:“ ^ 3.7.2”“ react-redux”:“ ^ 5.0.6”

我感觉这主要是由于我对我的module.hot.accept调用的位置和放置方式缺乏了解(如果可以包含多个呢?)。相关代码如下。

boot.js(入口点)

import { Provider } from 'react-redux';
import { AppContainer } from 'react-hot-loader';
import { ConnectedRouter } from 'react-router-redux';

import App from './App';

import { configureStore, history } from './store/configureStore';

let store = configureStore();

function renderApp() {
    ReactDOM.render(
      <AppContainer>
        <Provider store={store}>
          <ConnectedRouter history={history}>
            <App />
          </ConnectedRouter>
        </Provider>
      </AppContainer>
      , document.getElementById("app"));
}

renderApp();

if (module.hot) {
    module.hot.accept(() => {
        renderApp();
    })
}
Run Code Online (Sandbox Code Playgroud)

configureStore.js

import createHistory from 'history/createBrowserHistory';
import { createStore, combineReducers, compose, applyMiddleware } from 'redux';
import { routerMiddleware, routerReducer } from 'react-router-redux';
import thunk from 'redux-thunk';

import DevTools from '../components/DevTools';

import * as rootReducer from '../services/rootReducer';

const composeEnhancers = compose;

export const history = createHistory();

const middleware = routerMiddleware(history);

export function configureStore(initialState) {
  const reducers = { ...rootReducer, router: routerReducer };

  const store =  createStore(
    combineReducers(reducers),
    initialState,
    composeEnhancers(
      applyMiddleware(middleware, thunk),
      DevTools.instrument()
    )
  );

  if (module.hot) {
    module.hot.accept('../services/rootReducer', () => {
      const nextRootReducer = require('../services/rootReducer').default;
      const finalReducer = {...nextRootReducer, router: routerReducer };
      store.replaceReducer(finalReducer);
    })
  }

  return store;
}
Run Code Online (Sandbox Code Playgroud)

我的configureStore中的module.hot.accept从未真正调用过,因为boot.js中的父项是。只能有一个吗?

我如何摆脱这个错误?

或者,让我改写一下:如何消除此错误,并使用redux存储正确设置反应热加载环境?

相关的Github问题:

https://github.com/reactjs/react-redux/issues/259

Jac*_*ack 5

经过进一步研究,结果表明问题出在boot.js中accept调用的范围。由于它本质上是在从根级别应用程序监视所有内容,因此整个应用程序都在化简版更改时重新加载,因此从未调用化简版的HMR接受。以下是工作版本。

boot.js

if (module.hot) {
    module.hot.accept('./containers/App.js', () => {
        const nextApp = require('./containers/App').default;
        renderApp(nextApp);
    })
}
Run Code Online (Sandbox Code Playgroud)

configureStore.js

  if (module.hot) {
    module.hot.accept('../services/rootReducer', () => {
      const nextRootReducer = require('../services/rootReducer');
      const finalReducer = {...nextRootReducer, router: routerReducer };
      store.replaceReducer(combineReducers(finalReducer));
    })
  }
Run Code Online (Sandbox Code Playgroud)