Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/observed-computeds-track-action-dependencies.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"mobx": patch
---

Fix `onBecomeObserved` not firing for dependencies gained when an observed computed is recomputed inside an action.
40 changes: 40 additions & 0 deletions packages/mobx/__tests__/base/become-observed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -615,3 +615,43 @@ test("onBecomeObserved cascades through a chain of cached computeds #4547", () =
disposeAutorun!()
expect(events).toEqual(["BO", "BUO"])
})

test("onBecomeObserved fires for a dependency gained by an observed computed in an action #3674", () => {
const events: string[] = []
const enabled = observable.box(false)
const resource = observable.box(1)
onBecomeObserved(resource, () => events.push("BO"))
onBecomeUnobserved(resource, () => events.push("BUO"))
const derived = computed(() => (enabled.get() ? resource.get() : null))
const disposeAutorun = autorun(() => {
derived.get()
})

runInAction(() => {
enabled.set(true)
derived.get()
})

expect(events).toEqual(["BO"])

disposeAutorun()
expect(events).toEqual(["BO", "BUO"])
})

test("temporary computed observers do not activate lifecycle hooks", () => {
const events: string[] = []
const enabled = observable.box(false)
const resource = observable.box(1)
onBecomeObserved(resource, () => events.push("BO"))
onBecomeUnobserved(resource, () => events.push("BUO"))
const inner = computed(() => (enabled.get() ? resource.get() : null))
const outer = computed(() => inner.get())

runInAction(() => {
outer.get()
enabled.set(true)
inner.get()
})

expect(events).toEqual([])
})
5 changes: 4 additions & 1 deletion packages/mobx/src/core/computedvalue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,10 @@ export class ComputedValue<T> implements IObservable, IComputedValue<T>, IDeriva
reportObserved(this)
if (shouldCompute(this)) {
let prevTrackingContext = globalState.trackingContext
if (this.keepAlive_ && !prevTrackingContext) {
if (!prevTrackingContext && (this.keepAlive_ || this.isBeingObserved)) {
// An observed or keep-alive computed can be recomputed by an untracked
// read, for example from inside an action. Its dependencies are still
// transitively observed and must fire their lifecycle hooks
globalState.trackingContext = this
}
if (this.trackAndCompute()) {
Expand Down