In case of use interval
in redux-observable's epic, this observer is not remove when reload with HMR working.
This observable is not effect store, but it is feel bad.
Solution: Use Subject to fire with module.hot.dispose
and stop
FYI: If you use typescript, @types/webpack-env includes module.hot
type.
import { combineEpics } from "redux-observable"
import { interval, Subject } from "rxjs"
import { map, takeUntil } from "rxjs/operators"
const disposer = new Subject() // Setup subject for dispose.
export const timerEpic = () => {
return interval(1000).pipe(
takeUntil(disposer), // stop when dispose subscribed.
map((time) => ({
type: "TIMER",
value: time
}))
)
}
if (module.hot) {
module.hot.dispose((data) => {
disposer.next() // send dispose when fire HMR dispose event
})
}
Split HMR part
You can split related HMR code like this.
// hotReload.ts
import { Subject } from "rxjs"
import { takeUntil } from "rxjs/operators"
const hmrDisposer = new Subject()
export const registerDisposeHandler = (module) => {
if (module.hot) {
module.hot.dispose(() => hmrDisposer.next())
}
}
export const takeUntilHotReload = () => takeUntil(hmrDisposer)
Attention, you need call dispose hook on rootEpic file.
export const rootEpic = combineEpics(pingEpic)
// DO WRITE with ROOT EPIC.
registerDisposeHandler(module)
Top comments (0)