What does the when() function do?
Simple definition
when(predicate, effect?)is a function that waits until a condition (predicate) based on observable data becomestrue, and runs an action (effect) once, after which it automatically unsubscribes.
Syntax
import { when } from 'mobx'
// Option 1: with a callback (imperative)
when(
() => condition === true, // condition (predicate)
() => doSomething() // action (effect)
)
// Option 2: as a promise (asynchronous)
await when(() => condition === true)Example 1 - basic (with a side effect)
import { makeAutoObservable, when } from 'mobx'
class Store {
data = null
constructor() {
makeAutoObservable(this)
this.loadData()
}
async loadData() {
setTimeout(() => {
this.data = { user: 'Alex' }
}, 2000)
}
}
const store = new Store()
when(
() => store.data !== null, // wait until data appears
() => console.log('Data is loaded:', store.data)
)What happens:
when()subscribes to changes of every observable mentioned in the condition (store.data).- While
store.dataisnull, nothing happens. - As soon as
store.datachanges and the condition returnstrue, MobX calls the second callback. - The subscription is removed automatically - no memory leaks.
Example 2 - with a promise (await)
when() can be used in async/await style:
await when(() => store.user != null)
console.log('User is ready:', store.user)This is especially convenient when you need to wait for state to load (for example, data from an API) and continue the logic only after that.
Example 3 - cancelling the wait
The when() function returns a disposer - a function that cancels the wait if it is no longer needed:
const cancel = when(
() => store.user != null,
() => console.log('User loaded!')
)
// If you want to cancel the subscription earlier
cancel()Reactive nature
When you call when(() => someCondition), MobX:
- runs the condition inside a reactive context;
- remembers which observable values were used;
- on any change to those observables recomputes the condition;
- if the result becomes
true→ callseffectand destroys the reaction.
So when() is like a "one-time autorun" that fires only once, when the condition is met.
Difference between when, autorun, reaction
| Function | Fires | Repeats | Auto-unsubscribe |
|---|---|---|---|
autorun(fn) | on first run and on every dependency change | Yes | No |
reaction(dataFn, effect) | when the value returned by dataFn changes | Yes | No |
when(predicate, effect) | when the predicate becomes true | No | Yes |
Example 4 - practical use
Scenario: wait until the user logs in.
when(
() => authStore.isLoggedIn === true,
() => router.navigate('/dashboard')
)MobX watches authStore.isLoggedIn itself.
When the user logs in, the callback runs and the subscription disappears.
Summary
| What it does | In short |
|---|---|
when() | Reacts when the condition first becomes true |
| Subscribes to dependencies | Yes (automatically) |
| Automatically unsubscribes | Yes |
| Can be used with async/await | Yes |
| Returns a disposer | Yes |
| Typical cases | waiting for data loading, authorization, state flags |
A short formula:
when()= "Do something when X first becomes true, and forget about me".
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.