rt2zz / redux-persist

persist and rehydrate a redux store
MIT License
12.96k stars 866 forks source link

PersistGate is not reset bootstrapped with module.hot.accept #1244

Open Timson020 opened 4 years ago

Timson020 commented 4 years ago

store.js

import { createStore, applyMiddleware } from 'redux'
import { createLogger } from 'redux-logger'
import { persistReducer, persistStore, createTransform } from 'redux-persist'
import storage from 'redux-persist/lib/storage'

import reducers from '@/reducers'

const whitelist = [ 'User' ]

const ISDEV = process.env.NODE_ENV === 'development'

const logger = createLogger({
    stateTransformer: (state) => {
        let newState = {}
        for (let i of Object.keys(state)) {
            newState[i] = state[i].toJSON ? state[i].toJSON() : state[i]
        }
        return newState
    },
})

const transfromer = createTransform(
    // set
    (state) => state.toJSON(),
    // get
    (state) => state,
    // config
    { whitelist }
)

const middleware = ISDEV ? [ logger ] : []

const persistReducerConfig = {
    key: `adswave-bms-store-${JSON.sessionVersion}`,
    storage,
    version: 1,
    whitelist,
    keyPrefix: ISDEV ? 'test-' : 'release-',
    transforms: [ transfromer ],
    debug: ISDEV
}

function create() {
    const store = createStore(persistReducer(persistReducerConfig, reducers), applyMiddleware(...middleware))
    if (module.hot) {
        // Enable Webpack hot module replacement for reducers
        module.hot.accept('./reducers', () => {
            const nextRootReducer = require('./reducers').default
            store.replaceReducer(nextRootReducer)
        })
    }
    const persistor = persistStore(store)
    return { store, persistor }
}

export default create

app.js

import React from 'react'
import ReactDOM from 'react-dom'
import { PersistGate } from 'redux-persist/integration/react'
import { BrowserRouter, Route, Switch } from 'react-router-dom'
import { Provider } from 'react-redux'

import createStore from './store'
import Routes from './routes'

const { store, persistor } = createStore()

ReactDOM.hydrate(<Provider store={store}>
    <PersistGate loading={null} persistor={persistor}>
        <BrowserRouter>
            <Switch>
                {
                    Routes.map(({ path, exact, Component }) => {
                        return <Route exact={exact} key={path} path={path} render={() => <Component />} />
                    })
                }
            </Switch>
        </BrowserRouter>
    </PersistGate>
</Provider>
, document.getElementById('application'))

when i update something page

Action: persist/REHYDRATE lated than page componentWillMount

it's mean PersistGate Component is does't work in module.hot.accept

then i debug in redux-persist/es/integration/react.js

discovery this.state.bootstrapped is true

first in application this.state.bootstrapped is false then componetWillComponent Change true