首页 文章

在Redux-DevTools中使用Webpack HMR插件时,为什么App状态会重置?

提问于
浏览
2

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 回答

  • -1

    即使我无法复制问题(欢迎jsfiddle),更换后更新商店应该有所帮助:

    if (module.hot) {
      module.hot.accept('redux/modules', () => {
      store.replaceReducer(require('redux/modules').default)
      if (window.devToolsExtension) window.devToolsExtension.updateStore(store)
    })}
    
  • 0

    使用redux-persist持久化应用程序状态,通过页面刷新操作和选项卡或浏览器关闭 .

  • 0

    在App index.js中删除此方法

    if (module.hot) {
    module.hot.accept('redux/modules', () => {
      store.replaceReducer(require('redux/modules').default)
    })}
    

相关问题