我正在使用带有 Redux Devtools Chrome 扩展的 webpack 热模块替换(HMR)插件。但是,每当 HMR 运行时,Redux 本地应用程序状态都会重置为所有初始值。我的网络配置如下:
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)
这是我的主要应用 index.js 的样子:
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)
})