2

我正在使用带有 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)
})
4

3 回答 3

0

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

if (module.hot) {
  module.hot.accept('redux/modules', () => {
  store.replaceReducer(require('redux/modules').default)
  if (window.devToolsExtension) window.devToolsExtension.updateStore(store)
})}
于 2016-08-05T09:25:44.783 回答
0

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

于 2017-01-06T02:57:45.847 回答
-1

在您的 App index.js 中删除此方法

if (module.hot) {
module.hot.accept('redux/modules', () => {
  store.replaceReducer(require('redux/modules').default)
})}
于 2016-06-21T10:32:27.253 回答