Skip to main content

Що таке computed value в MobX?

Що таке computed value

Computed value (або "обчислювана властивість") - це значення, яке автоматично перераховується, коли змінюються спостережувані (observable) дані, від яких воно залежить.

Іншими словами:

computed - це "реактивний get", який MobX кешує і перераховує лише за потреби.


1. Приклад наочно

javascript
import { makeAutoObservable } from "mobx" class TodoStore { todos = [ { title: "Купити хліб", done: true }, { title: "Подзвонити другу", done: false }, ] constructor() { makeAutoObservable(this) } // computed get completedCount() { return this.todos.filter(t => t.done).length } } const store = new TodoStore() console.log(store.completedCount) // 1 store.todos[1].done = true console.log(store.completedCount) // 2

MobX сам стежить, які observable використовуються в completedCount, і перерахує його лише коли зміняться потрібні поля (todos[i].done).


2. У чому відмінність від звичайного геттера

Якби це був звичайний JS-геттер, він би перераховувався при кожному виклику, навіть якщо нічого не змінилося.

Computed у MobX працює інакше:

  • він запам'ятовує (кешує) останнє значення;
  • перераховується лише якщо залежності змінилися.

Це робить computed дуже ефективним.


3. Як MobX відстежує залежності

MobX будує граф залежностей між observable і computed. Коли observable-дані змінюються, MobX інвалідує лише потрібні computed-властивості.

Приблизно так:

javascript
todos.done → completedCount → UI

Якщо todos змінилися → перерахувати completedCount → оновити UI. Якщо змінилося щось інше (не пов'язане з todos) - completedCount не чіпається.


4. Як оголосити computed

Є 2 способи:

Через геттер:

javascript
get fullName() { return `${this.firstName} ${this.lastName}` }

(Якщо використовується makeAutoObservable, MobX сам визначить, що це computed.)

Через makeObservable:

javascript
import { makeObservable, observable, computed } from "mobx" class UserStore { firstName = "Alex" lastName = "Smith" constructor() { makeObservable(this, { firstName: observable, lastName: observable, fullName: computed, }) } get fullName() { return `${this.firstName} ${this.lastName}` } }

5. Переваги computed

ПеревагаОпис
Автоматичне оновленняПерераховується при зміні залежностей
КешуванняНе перераховується без потреби
ІммутабельністьНе можна напряму змінити (read-only)
Проста декларативністьПоказує "що залежить від чого"
Оптимізація UIКомпоненти re-render'яться лише при зміні залежних даних

6. Відмінність computed від action і observable

ТипЩо робитьЗмінює дані?Реактивно оновлюється?
observableзберігає станТакТак
actionзмінює observableТакНі
computedобчислює похідні значенняНіТак

7. Приклад з реактивним UI

javascript
import { observer } from "mobx-react-lite" const TodoInfo = observer(({ store }) => ( <div> <p>Усього завдань: {store.todos.length}</p> <p>Виконано: {store.completedCount}</p> </div> ))

Компонент автоматично оновиться, коли зміниться todos або перерахується completedCount.


8. Кешування в дії

javascript
console.log(store.completedCount) // 2 - обчислить console.log(store.completedCount) // 2 - візьме з кешу store.todos.push({ title: "Нова", done: false }) console.log(store.completedCount) // 2 - перерахує знову

MobX кешує результат, поки observable-залежності не змінилися.


9. "computed value" поза класами (реактивна функція)

Можна створювати computed-значення вручну:

javascript
import { observable, computed } from "mobx" const price = observable.box(100) const quantity = observable.box(2) const total = computed(() => price.get() * quantity.get()) console.log(total.get()) // 200 price.set(120) console.log(total.get()) // 240

Тут computed() працює як реактивна функція, MobX сам відстежує залежності між price, quantity і total.


ПІДСУМОК

Computed value - це похідне (derived) значення, яке MobX автоматично перераховує при зміні залежностей, і кешує, щоб не робити зайву роботу.


Формула запам'ятовування

Observable → зберігає дані Action → змінює дані Computed → обчислює з даних Observer (React) → відображає дані

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.