observableArray
observableArray creates a reactive array. It implements the standard Array
interface via a Proxy, so reads are tracked and mutations trigger reactions.
Signature
function observableArray<T>(
initialValue?: T[],
options?: ArrayOptions,
): ObservableArray<T>
interface ArrayOptions {
name?: string
comparer?: EqualityComparison
shallow?: boolean
}
interface ObservableArray<T> extends Array<T> {
replace(newArray: T[]): T[]
remove(item: T): number
clear(): T[]
toJSON(): T[]
}
Parameters
| Parameter | Type | Description |
|---|---|---|
initialValue |
T[] |
Starting elements (default: empty) |
options.name |
string |
Debug name |
options.comparer |
EqualityComparison |
Equality check for element values |
options.shallow |
boolean |
If true, elements are not recursively made observable |
Basic usage
import { autorun, observableArray } from "@fobx/core"
const items = observableArray(["a", "b", "c"])
const stop = autorun(() => {
console.log("items:", items.join(", "))
})
// prints: items: a, b, c
items.push("d")
// prints: items: a, b, c, d
items[0] = "A"
// prints: items: A, b, c, d
items.splice(1, 1)
// prints: items: A, c, d
stop()
Tracked operations
Any read that touches the array content creates a dependency:
- Index access:
arr[i] length- Iteration:
for...of, spread,Array.from() - Methods:
map,filter,find,findIndex,some,every,reduce,includes,indexOf,lastIndexOf,join,slice,flat,flatMap,at,entries,values,keys,forEach,toString
Mutating operations
These trigger notification to observers:
push,pop,shift,unshiftsplice,sort,reversefill,copyWithinarr[i] = value(index assignment)arr.length = n(truncation)
Shallow mode
By default, plain objects and collections added to the array are recursively
converted to observables. Use shallow: true to prevent this:
const shallow = observableArray<{ x: number }>([], { shallow: true })
const obj = { x: 1 }
shallow.push(obj)
// obj is NOT wrapped — it's stored as-is
console.log(shallow[0] === obj) // true
Deep mode (default)
In deep mode, plain objects and arrays added to the array are automatically converted to observable objects/arrays. The converted value is a new observable copy, not the original reference:
const deep = observableArray<{ x: number }>([])
const obj = { x: 1 }
deep.push(obj)
// deep[0] is an observable copy of obj, not the same reference
console.log(deep[0] === obj) // false
Inside observable objects
When you assign an array to a property on an observable() object with the
"observable" annotation (default), the array is automatically wrapped in
observableArray:
import { observable } from "@fobx/core"
const store = observable({
items: [1, 2, 3],
})
// store.items is now an observableArray
store.items.push(4) // triggers reactions
The same applies to class instances using makeObservable() with an explicit
"observable" annotation on the array property.