Skip to content

Commit 57b5567

Browse files
committed
fix: expose function to clear timers and allow immediate test exit
Exposes `clearTimers` function which clears up background 'aborted render' reactions immediately. Some test frameworks such as Jest prevent exit unless all such timers are cleared. For: mobx/mobx#2528
1 parent 9219288 commit 57b5567

File tree

4 files changed

+33
-1
lines changed

4 files changed

+33
-1
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"mobx-react-lite": patch
3+
---
4+
5+
expose `clearTimers` function to tidy up background timers, allowing test frameworks such as Jest to exit immediately

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,19 @@ Above imports are for a convenience to utilize standard versions of batching. If
154154
import { observerBatching } from "mobx-react-lite"
155155
observerBatching(customBatchedUpdates)
156156
```
157+
158+
## Testing
159+
160+
In order to avoid memory leaks due to aborted renders from React
161+
fiber handling or React `StrictMode`, this library needs to
162+
run timers to tidy up the remains of the aborted renders.
163+
164+
This can cause issues with test frameworks such as Jest
165+
which require that timers be cleaned up before the tests
166+
can exit.
167+
168+
### **`clearTimers()**
169+
170+
Call `clearTimers()` in the `afterEach` of your tests to ensure
171+
that `mobx-react-lite` cleans up immediately and allows tests
172+
to exit.

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export { Observer } from "./ObserverComponent"
1414
export { useLocalObservable } from "./useLocalObservable"
1515
export { useLocalStore } from "./useLocalStore"
1616
export { useAsObservableSource } from "./useAsObservableSource"
17+
export { resetCleanupScheduleForTests as clearTimers } from "./utils/reactionCleanupTracking"
1718

1819
export function useObserver<T>(fn: () => T, baseComponentName: string = "observed"): T {
1920
if ("production" !== process.env.NODE_ENV) {

src/utils/reactionCleanupTracking.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,19 @@ export function forceCleanupTimerToRunNowForTests() {
119119

120120
/* istanbul ignore next */
121121
export function resetCleanupScheduleForTests() {
122+
if (uncommittedReactionRefs.size > 0) {
123+
for (const ref of uncommittedReactionRefs) {
124+
const tracking = ref.current
125+
if (tracking) {
126+
tracking.reaction.dispose()
127+
ref.current = null
128+
}
129+
}
130+
uncommittedReactionRefs.clear()
131+
}
132+
122133
if (reactionCleanupHandle) {
123134
clearTimeout(reactionCleanupHandle)
124135
reactionCleanupHandle = undefined
125136
}
126-
uncommittedReactionRefs.clear()
127137
}

0 commit comments

Comments
 (0)