I'm using webpack Hot Module Replacement(HMR) Plugin with Redux Devtools Chrome extension. However whenever the HMR runs, the Redux local app state resets to all the initial values. My webconfig is the following:
import webpack from 'webpack'
import path from 'path'
import HtmlWebpackPlugin from 'html-webpack-plugin'
const LAUNCH_COMMAND = process.env.npm_lifecycle_event
const isProduction = LAUNCH_COMMAND === 'production'
process.env.BABEL_ENV = LAUNCH_COMMAND
const PATHS = {
app: path.join(__dirname, 'app'),
build: path.join(__dirname, 'dist')
}
const HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
template: PATHS.app + '/index.html',
filename: 'index.html',
inject: 'body'
})
const productionPlugin = new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
}
})
const productionPlugin2 = new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false
}
})
const base = {
entry: [
'babel-polyfill',
PATHS.app
],
output: {
path: PATHS.build,
filename: 'index_bundle.js'
},
module: {
loaders: [
{test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'},
{test: /\.css$/, loader: 'style!css?sourceMap&modules&localIdentName=[name]__[local]___[hash:base64:5]'}
]
},
resolve: {
root: path.resolve('./app')
}
}
const developmentConfig = {
devtool: 'cheap-module-inline-source-map',
devServer: {
contentBase: PATHS.build,
historyApiFallback: true,
hot: true,
inline: true,
progress: true
},
plugins: [HTMLWebpackPluginConfig, new webpack.HotModuleReplacementPlugin()]
}
const productionConfig = {
devtool: 'cheap-module-source-map',
plugins: [HTMLWebpackPluginConfig, productionPlugin, productionPlugin2]
}
export default Object.assign({}, base, isProduction === true ? productionConfig : developmentConfig)
And here is what my main App index.js looks like:
import React from 'react'
import ReactDOM from 'react-dom'
import getRoutes from './config/routes'
import { createStore, applyMiddleware, compose, combineReducers } from 'redux'
import { Provider } from 'react-redux'
import { authUser, unauthUser, fetchingUserSuccess } from 'redux/modules/users'
import ReduxThunk from 'redux-thunk'
import { initAuth, formatUserInfo } from 'helpers/auth'
import * as reducers from 'redux/modules'
let reducer = combineReducers(reducers)
// const store = createStore(
// reducer,
// compose(applyMiddleware(ReduxThunk),
// window.devToolsExtension ? window.devToolsExtension() : f => f))
function configureStore () {
const store = createStore(
reducer,
compose(applyMiddleware(ReduxThunk),
window.devToolsExtension ? window.devToolsExtension() : f => f))
if (module.hot) {
module.hot.accept('redux/modules', () => {
store.replaceReducer(require('redux/modules').default)
})
}
return store
}
const store = configureStore()
export function checkAuth (nextState, replace) {
// debugger
// console.log('isAuthed from Main container mount')
// const isAuthed = checkIfAuthed(store)
const isAuthed = store.getState().users.isAuthed
// const isAuthed = store.getState().isAuthed
console.log('isAuthed from checkAuth method', isAuthed)
const nextPathName = nextState.location.pathname
console.log('nextPathName', nextPathName)
// debugger
if ((isAuthed !== true) && (nextPathName !== 'auth')) {
// debugger
console.log('replaced path to auth')
replace('auth')
} else if ((nextPathName === '/' || nextPathName === 'auth') && (isAuthed === true)) {
// debugger
console.log('replaced path to feed')
replace('feed')
}
}
initAuth()
.then((user) => {
if (user !== null) {
console.log('intial user', user.displayName)
store.dispatch(authUser(user.uid))
const userInfo = formatUserInfo(user.displayName, user.photoURL, user.uid)
store.dispatch(fetchingUserSuccess(user.uid, userInfo))
} else {
console.log('intial user is :', user)
store.dispatch(unauthUser())
}
ReactDOM.render(
<Provider store = {store}>
{getRoutes(checkAuth)}
</Provider>,
document.getElementById('app')
)
})
.catch((error) => {
console.log('ERROR', error)
})
3 回答
即使我无法复制问题(欢迎jsfiddle),更换后更新商店应该有所帮助:
使用redux-persist持久化应用程序状态,通过页面刷新操作和选项卡或浏览器关闭 .