与 Redux 反应热重载
React Hot Reload with Redux
我已经获得了与 HMR / React Hot Reloader 相关的所有内容,因为它与视图有关。但是在添加 redux、react-redux 等之后......每当我修改视图或 reducer 时,我都会收到以下错误:
<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.
跟随错误中的 link 导致 2 岁 post 关于显式使用 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();
})
}
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;
}
我的 configureStore 中的 module.hot.accept 从未真正被调用,因为 boot.js 中的父项被调用了。难道只有1个?!
如何摆脱这个错误?
或者,让我换个说法:我如何摆脱这个错误并正确设置一个带有 redux 存储的 React 热加载环境?
可能相关的 Github 问题:
经过进一步研究,发现问题出在boot.js中accept调用的范围。由于它本质上是从根级别应用程序观察一切,整个应用程序在 reducer 更改时重新加载,因此从未调用过 reducer 的 HMR accept。以下是工作版本。
boot.js
if (module.hot) {
module.hot.accept('./containers/App.js', () => {
const nextApp = require('./containers/App').default;
renderApp(nextApp);
})
}
configureStore.js
if (module.hot) {
module.hot.accept('../services/rootReducer', () => {
const nextRootReducer = require('../services/rootReducer');
const finalReducer = {...nextRootReducer, router: routerReducer };
store.replaceReducer(combineReducers(finalReducer));
})
}
我已经获得了与 HMR / React Hot Reloader 相关的所有内容,因为它与视图有关。但是在添加 redux、react-redux 等之后......每当我修改视图或 reducer 时,我都会收到以下错误:
<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.
跟随错误中的 link 导致 2 岁 post 关于显式使用 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();
})
}
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;
}
我的 configureStore 中的 module.hot.accept 从未真正被调用,因为 boot.js 中的父项被调用了。难道只有1个?!
如何摆脱这个错误?
或者,让我换个说法:我如何摆脱这个错误并正确设置一个带有 redux 存储的 React 热加载环境?
可能相关的 Github 问题:
经过进一步研究,发现问题出在boot.js中accept调用的范围。由于它本质上是从根级别应用程序观察一切,整个应用程序在 reducer 更改时重新加载,因此从未调用过 reducer 的 HMR accept。以下是工作版本。
boot.js
if (module.hot) {
module.hot.accept('./containers/App.js', () => {
const nextApp = require('./containers/App').default;
renderApp(nextApp);
})
}
configureStore.js
if (module.hot) {
module.hot.accept('../services/rootReducer', () => {
const nextRootReducer = require('../services/rootReducer');
const finalReducer = {...nextRootReducer, router: routerReducer };
store.replaceReducer(combineReducers(finalReducer));
})
}