Tracking
observe
, when
, computed
, and React observer
components automatically track when you call get()
or use array looping functions, so you generally don't have to think about it unless you want to specifically optimize. When an observable is tracked, it will re-run on any changes anywhere within the observable and its children.
These operations track:
- Call
get()
on an observable:settings.get()
- Array looping functions (shallow listener):
arr.map(settings.accounts, () => ...)
- Accessing array length (shallow listener):
if (arr.length > 0) ...
- Object.keys (shallow listener):
Object.keys(settings)
These operation do not track:
- Accessing through an observable:
state.settings
- Call
peek()
on an observable:settings.peek()
Some examples of the automatic behavior:
const state = observable({
settings: {
theme: 'dark'
},
chats: {
messages: [
{ id: 0, text: 'hi' }
]
}
})
observe(() => {
// Example 1:
const theme = state.settings.theme.get()
// Tracking [state.settings.theme] because of get()
// Example 2:
const settings = state.settings
// Not tracking because it's an object
const theme = settings.theme.get()
// Tracking [state.settings.theme] because of get()
// Example 3:
const themeObs = state.settings.theme
// Not tracking with no get()
// Example 4:
state.chats.messages.map(m => <Message key={m.get().id} message={m} />)
// Tracking [state.chats.messages (shallow)] because of map()
// Example 5:
Object.keys(state.settings)
// Tracking [state.settings (shallow)]
})
The automatic behavior can be modified with two observable functions:
Function | Value | Tracked |
---|---|---|
get() | raw | yes |
get(true) | raw | shallow |
peek() | raw | no |
get()
get
returns the raw data of an observable and tracks it, so you can work with it without doing any further tracking. You may want to use get()
to:
- Get the value of an observable wrapper of a primitive
- Track this object and not its individual fields. Minimizing the number of listeners is better for performance.
const theme = state.settings.theme.get()
// ✅ Tracking [state.settings.theme]
peek()
peek()
returns the raw value in the same way as get()
, but it does not automatically track it. Use this when you don't want the component/observing context to update when the value changes.
const theme = state.settings.theme.peek()
// Not tracking
shallow modifier
get()
observes recursively by default, so any child changing will cause an update. You can modify it to be a shallow listener by just adding a true
parameter. This can be useful when a component only needs to re-render if an object's keys or an array's items change.
const state = observable({ messages: [] })
observe(() => {
// Only need this to update when messages added/removed
const messages = state.messages.get(true)
console.log('Latest message', messages[0])
})