Как реагировать на изменения объекта

  —  2 минуты

#theory#useful#javascript#code#web#patterns
Читать статью в Telegram

В JavaScript обычные объекты не умеют уведомлять о своих изменениях, однако эту задачу можно решить с помощью Proxy

Proxy — это специальный встроенный в язык объект-обёртка, который позволяет изменить поведение других объектов, перехватывая действия над ними

new Proxy(target, handlers) создаёт прокси для объекта target, где handler содержит ловушки для перехвата операций

Ловушек много — get, set, deleteProperty, has... (подробнее на MDN) — каждая из ловушек переопределяет реакцию объекта на взаимодействие с ним

Например, можно переопределить поведение объекта при обращении к какому-нибудь из его свойств:

javascript
1const user = { name: "Денис", age: 23 };
2
3const proxyUser = new Proxy(user, {
4  get(target, key) {
5    return key in target ? target[key] : "Не найдено";
6  }
7});
8
9proxyUser.name // "Денис"
10proxyUser.city // "Не найдено"
11

Но это лишь частный случай, можно сделать более утилитарный пример:

javascript
1const reactive = (obj, callback) => {
2  return new Proxy(obj, {
3    set(target, key, value) {
4      target[key] = value; // обновляем значение
5      callback(key, value); // вызываем реакцию
6      return true;
7    }
8  });
9};
10
11// Используем:
12const state = reactive({ count: 0 }, (key, value) => {
13  console.log(`Свойство "${key}" изменилось:`, value);
14});
15
16state.count = 1; // Лог: "Свойство 'count' изменилось: 1"
17state.count = 5; // Лог: "Свойство 'count' изменилось: 5"
18

Прикрутить сюда типы и рекурсивный вызов функции reactive на каждый вложенный объект и у вас почти получится свой vue.js 🗿

Сам Proxy — это крайне нишевый инструмент, особенно в экосистеме реакта, где его встретить крайне сложно. Обычно можно обойтись более простыми вещами, но знать про прокси тоже нужно, может и пригодится. По крайней мере, у меня такой кейс на практике всё же был

В первую очередь прокси удобен конечно же для создания реактивных систем, но также его можно применять, например, для валидации свойств и логирования

Удобно, что Proxy крайне прост и к нему можно прикрутить что угодно. Например, к прокси можно прилепить zod для валидации, как это сделано в zoxy. Тут вы ограничены лишь своей фантазией

Статья была полезной?