Що таке observable у MobX?
Просте визначення
Observable - це спостережуване значення: звичайна змінна, об'єкт чи масив, обгорнуті в механізм відстеження змін.
Коли observable-значення змінюється, MobX автоматично сповіщає всі обчислення і компоненти, які його використовують.
Аналогія
Уяви, що observable - це як "реактивна комірка" в Excel:
якщо формула (=A1 + A2) залежить від комірок A1 і A2, то при зміні їхніх значень Excel сам перерахує формулу.
Ось MobX робить те саме з даними та інтерфейсом.
Приклад 1 - базовий observable
import { makeObservable, observable, action } from 'mobx'
class Counter {
count = 0
constructor() {
makeObservable(this, {
count: observable, // спостережувана властивість
increment: action,
})
}
increment() {
this.count++
}
}
const counter = new Counter()Тепер counter.count - observable.
Будь-який код (чи компонент), що його читає, автоматично стане залежним від нього.
Приклад 2 - автоматичне відстеження (observer)
import { observer } from 'mobx-react-lite'
const counter = new Counter()
const CounterView = observer(() => (
<div>
<p>{counter.count}</p> {/* просто читаємо observable */}
<button onClick={() => counter.increment()}>+</button>
</div>
))Коли counter.count зміниться, MobX:
- виявить, що компонент
CounterViewчитавcount, - "запам'ятає" цю залежність,
- перемалює тільки цей компонент при наступній зміні.
Ніяких useState, useEffect, subscribe - все "магічно" реактивно.
Як це працює під капотом
MobX створює проксі-обгортку навколо значення і відстежує:
- хто читає значення (
get); - хто його змінює (
set).
Коли observable читається, MobX запам'ятовує активну реакцію (наприклад, компонент). Коли значення оновлюється, MobX сповіщає тільки ті реакції, які його використовували.
Цей механізм називається fine-grained reactivity (тонкозерниста реактивність).
Приклад 3 - об'єкт і масиви
import { observable } from 'mobx'
const state = observable({
user: { name: 'Tim' },
todos: [],
})
// автоматичне відстеження
state.user.name = 'Alex'
state.todos.push({ text: 'learn MobX', done: false })Всі вкладені поля всередині observable() теж стають спостережуваними - MobX "рекурсивно" робить їх реактивними.
makeAutoObservable - сучасний спосіб
Сьогодні частіше використовують makeAutoObservable() - він сам визначає, які поля повинні бути observable, які computed, а які action:
import { makeAutoObservable } from 'mobx'
class TodoStore {
todos = []
constructor() {
makeAutoObservable(this) // все автоматично стає реактивним
}
get completedCount() {
return this.todos.filter(t => t.done).length
}
addTodo(text) {
this.todos.push({ text, done: false })
}
}MobX сам створить:
todos- observable (спостережувані дані);completedCount- computed (реактивне похідне значення);addTodo()- action (кероване змінення стану).
Види observable у MobX
| Тип | Що робить |
|---|---|
observable.box(value) | одне спостережуване значення (примітив) |
observable.object(obj) | робить об'єкт реактивним |
observable.map() | реактивна Map |
observable.array() | реактивний масив |
makeAutoObservable(this) | автоматично перетворює властивості класу на спостережувані |
Підсумок
Observable у MobX - це "живі" дані, за якими MobX стежить. Коли вони змінюються, все, що від них залежить (компоненти, обчислення, ефекти), оновлюється автоматично.
Якщо коротко
| Термін | Роль |
|---|---|
| observable | реактивний стан (дані) |
| computed | похідні значення (залежать від observable) |
| action | функції, що змінюють observable |
| observer | компонент-обгортка, що автоматично реагує на зміни |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.