Merhaba arkadaşlar, bugün başımı çok ağrıtan bir konuyu, Vue 3'ün kalbi olan reactivity sistemini ve onunla nasıl düzgün dans edeceğimizi konuşacağız. Özellikle array ve object'lerimizi güncellerken, "Neden ekranda değişiklik görmüyorum?" diye ekrana bakakaldığım o anları hepimiz yaşamışızdır. İşin sırrı, Vue 3'ün artık Object.defineProperty yerine Proxy kullanmasında yatıyor. Bu değişiklik çok güçlü ama bazı alışkanlıklarımızı da değiştirmemizi gerektiriyor.
Proxy Arkasında Neler Oluyor?
Vue 3, bir veriyi reactive hale getirdiğinde, aslında onun etrafına görünmez bir Proxy katmanı sarıyor. Bu proxy, o objenin property'lerine erişimi (get) ve değiştirilmesini (set) izliyor. Sorun şu ki, eğer siz bu proxy'yi değil de, orijinal objenin kendisini değiştirirseniz, Vue hiçbir şeyin değiştiğini anlayamıyor. Bu hatayı ilk gördüğümde, "Ama ben değiştirdim işte!" diye kafayı yemiştim.
Array'lerde En Sık Yapılan Hata: Index ile Atama
Eski alışkanlıkla, bir array'in belirli bir index'ini direkt değiştirmek reactivity'yi kırar. Aşağıdaki örnekte, `todoList` reactive olsa bile, ekran güncellenmeyecek.
Peki çözüm ne? İşte benim kullandığım en temiz çözüm: Array'in kendisini yeni bir referans ile değiştirmek. Ya da Vue'un bize sağladığı özel methodları kullanmak.
Object'lerde Yeni Property Eklemek
Bir reactive objeye sonradan yeni bir property eklemek de aynı derecede sinsi bir tuzak. Direkt atama yaparsanız, bu property reactive olmayacak.
Bunun için iki güvenli yol var. Birincisi, objeyi baştan tüm property'leri ile tanımlamak. Mümkün değilse, ikinci yolu kullanıyoruz: Vue.set benzeri, Vue 3'teki global fonksiyon.
Altın Kural ve Best Practice
Kafanız karışmasın, kilit nokta şu: Her zaman reactive değişkenin kendisini değiştirmeye çalışın, onun içindeki "ham" veriyi değil. `ref` kullanıyorsanız `.value` üzerinden, `reactive` kullanıyorsanız doğrudan değişkenin kendisi üzerinden, değişikliği Vue'un anlayacağı şekilde yapın.
Array'ler için mutating methodları (`push`, `pop`, `splice`, `shift`, `unshift`, `sort`, `reverse`) güvenle kullanabilirsiniz. Object'ler için ise property'leri baştan tanımlamak veya `set` kullanmak en sağlam yoldur.
Sonuç olarak, Proxy tabanlı sistem aslında bize daha temiz ve güçlü bir reactivity sunuyor. Sadece eski, direkt mutation alışkanlıklarımızdan kurtulmamız gerekiyor. Siz Vue 3'te array veya object güncellerken benzer sorunlarla karşılaştınız mı? "Ben şöyle yapıyorum" dediğiniz farklı bir püf noktanız var mı? Yorumlarda paylaşalım, hep birlikte öğrenelim!
Vue 3, bir veriyi reactive hale getirdiğinde, aslında onun etrafına görünmez bir Proxy katmanı sarıyor. Bu proxy, o objenin property'lerine erişimi (get) ve değiştirilmesini (set) izliyor. Sorun şu ki, eğer siz bu proxy'yi değil de, orijinal objenin kendisini değiştirirseniz, Vue hiçbir şeyin değiştiğini anlayamıyor. Bu hatayı ilk gördüğümde, "Ama ben değiştirdim işte!" diye kafayı yemiştim.
Eski alışkanlıkla, bir array'in belirli bir index'ini direkt değiştirmek reactivity'yi kırar. Aşağıdaki örnekte, `todoList` reactive olsa bile, ekran güncellenmeyecek.
JavaScript:
// BU ÇALIŞMAZ! (Reactivity kırılır)
const todoList = ref(['Kahve al', 'Kodu yaz', 'Test et']);
todoList.value[1] = 'Kodu yeniden yaz'; // Proxy bu değişikliği yakalayamaz.
Peki çözüm ne? İşte benim kullandığım en temiz çözüm: Array'in kendisini yeni bir referans ile değiştirmek. Ya da Vue'un bize sağladığı özel methodları kullanmak.
JavaScript:
// YÖNTEM 1: Tüm array'i değiştir (Temiz Çözüm)
todoList.value = [...todoList.value.slice(0, 1), 'Kodu yeniden yaz', ...todoList.value.slice(2)];
// YÖNTEM 2: Vue'un Reactivity-friendly methodlarını kullan
const todoList = reactive(['Kahve al', 'Kodu yaz', 'Test et']);
// splice, push, pop, shift gibi mutating methodlar Proxy tarafından yakalanır.
todoList.splice(1, 1, 'Kodu yeniden yaz');
Bir reactive objeye sonradan yeni bir property eklemek de aynı derecede sinsi bir tuzak. Direkt atama yaparsanız, bu property reactive olmayacak.
JavaScript:
const user = reactive({ name: 'Bingün', title: 'Geliştirici' });
// BU ÇALIŞMAZ! Yeni property reactive DEĞİL.
user.age = 30;
Bunun için iki güvenli yol var. Birincisi, objeyi baştan tüm property'leri ile tanımlamak. Mümkün değilse, ikinci yolu kullanıyoruz: Vue.set benzeri, Vue 3'teki global fonksiyon.
JavaScript:
// YÖNTEM 1: Baştan tanımla (En iyisi)
const user = reactive({ name: 'Bingün', title: 'Geliştirici', age: 30 });
// YÖNTEM 2: `set` fonksiyonunu kullan
import { set } from 'vue';
set(user, 'age', 30); // Artık 'age' property'si de reactive!
Kafanız karışmasın, kilit nokta şu: Her zaman reactive değişkenin kendisini değiştirmeye çalışın, onun içindeki "ham" veriyi değil. `ref` kullanıyorsanız `.value` üzerinden, `reactive` kullanıyorsanız doğrudan değişkenin kendisi üzerinden, değişikliği Vue'un anlayacağı şekilde yapın.
Array'ler için mutating methodları (`push`, `pop`, `splice`, `shift`, `unshift`, `sort`, `reverse`) güvenle kullanabilirsiniz. Object'ler için ise property'leri baştan tanımlamak veya `set` kullanmak en sağlam yoldur.
Sonuç olarak, Proxy tabanlı sistem aslında bize daha temiz ve güçlü bir reactivity sunuyor. Sadece eski, direkt mutation alışkanlıklarımızdan kurtulmamız gerekiyor. Siz Vue 3'te array veya object güncellerken benzer sorunlarla karşılaştınız mı? "Ben şöyle yapıyorum" dediğiniz farklı bir püf noktanız var mı? Yorumlarda paylaşalım, hep birlikte öğrenelim!