Skip to main content

Що робить `reactive()` у Vue 3?

1. Що робить reactive()

Функція reactive() приймає звичайний об'єкт і повертає його реактивну (проксійовану) версію.

javascript
import { reactive } from 'vue' const state = reactive({ count: 0, user: { name: 'Tim' } })

Тепер, коли ти зміниш будь-яку властивість об'єкта:

javascript
state.count++ state.user.name = 'Alex'

Vue автоматично відстежить ці зміни та оновить усі ефекти, обчислення чи компоненти, які від них залежать.


2. Як це працює під капотом

Під капотом reactive() створює Proxy-обгортку над переданим об'єктом.

Спрощено:

javascript
function reactive(target) { return new Proxy(target, { get(target, key, receiver) { // при зчитуванні значення реєструємо залежність track(target, key) const res = Reflect.get(target, key, receiver) // якщо значення - об'єкт, робимо його реактивним рекурсивно if (typeof res === 'object' && res !== null) { return reactive(res) } return res }, set(target, key, value, receiver) { const oldValue = target[key] const result = Reflect.set(target, key, value, receiver) // якщо значення справді змінилося - тригеримо оновлення if (oldValue !== value) { trigger(target, key) } return result } }) }

track() - запам'ятовує, що поточне обчислення (effect/render) залежить від цієї властивості. trigger() - оповіщає всі ефекти, що властивість змінилася.


3. Приклад «у дії»

javascript
import { reactive, effect } from 'vue' const state = reactive({ count: 0 }) effect(() => { console.log(`Кількість: ${state.count}`) }) state.count++ // "Кількість: 1"
  1. При першому виклику effect() Vue зчитує state.count -> викликає track().
  2. Vue "запам'ятовує": ця функція залежить від state.count.
  3. Коли state.count змінюється -> trigger() запускає effect() знову.
  4. Консоль друкує нове значення.

4. Що робить reactive() внутрішньо

ЕтапЩо робить Vue
1. Приймає об'єктПеревіряє, чи він уже не є реактивним
2. Створює ProxyПерехоплює get і set
3. При get -> track()Реєструє залежність
4. При set -> trigger()Повідомляє всі залежні ефекти
5. Повертає обгорткуЯка поводиться як вихідний об'єкт, але «реагує» на зміни

5. Відмінність від ref()

Характеристикаreactive()ref()
Тип данихОбгортає об'єктОбгортає примітив (число, рядок тощо)
ЗверненняПрямий доступ (state.count)Потрібен .value (count.value)
Вкладені об'єктиАвтоматично стають реактивнимиПотрібно обгортати вручну
Коли використовуватиДля складних станівДля простих значень

Приклад:

javascript
const state = reactive({ count: 0 }) const count = ref(0) state.count++ // реактивно count.value++ // реактивно

6. Важливі особливості

  1. reactive() працює лише з об'єктами Якщо передати примітив (число, рядок тощо), Vue просто поверне його як є:
javascript
reactive(10) // поверне 10, не реактивно
  1. Реактивність поширюється ліниво (deep reactive) Вкладені об'єкти стають реактивними лише при першому зверненні до них.
  2. Порівняння за посиланням Оскільки це Proxy, state !== rawObject:
javascript
const raw = { x: 1 } const proxy = reactive(raw) console.log(proxy === raw) // false
  1. Можна отримати оригінал за допомогою toRaw():
javascript
import { toRaw } from 'vue' const original = toRaw(state)
  1. Можна «заморозити» об'єкт від реактивності за допомогою markRaw():
javascript
import { markRaw } from 'vue' const nonReactive = markRaw({ foo: 'bar' })

7. Коли використовувати reactive()

  • Для об'єктів стану компонентів:

    javascript
    const form = reactive({ name: '', email: '', accepted: false })
  • Для складних структур (вкладені об'єкти, масиви, колекції):

    javascript
    const data = reactive({ users: [{ id: 1 }, { id: 2 }], meta: { total: 2 } })
  • Для централізованих сховищ стану (наприклад, без Vuex / Pinia):

    javascript
    export const store = reactive({ user: null, isAuth: false })

8. Підсумок

reactive() робить звичайний об'єкт реактивним за допомогою Proxy. Vue автоматично відстежує всі читання й записи його властивостей. Будь-які ефекти, шаблони чи обчислення, що залежать від цих властивостей, автоматично оновлюються при зміні даних.

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

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

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