import { ReactiveVar } from 'meteor/reactive-var';// Create with initial valueconst counter = new ReactiveVar(0);const message = new ReactiveVar('Hello');const user = new ReactiveVar(null);const settings = new ReactiveVar({ theme: 'dark', lang: 'en' });
const count = new ReactiveVar(0);// This computation depends on countTracker.autorun(() => { console.log('Count is:', count.get());});// Prints: Count is: 0count.set(1);// Prints: Count is: 1count.set(2);// Prints: Count is: 2
The default equality function (ReactiveVar._isEqual):
// These are considered equal:var1.set(42);var1.set(42); // No invalidationvar2.set(true);var2.set(true); // No invalidationvar3.set('hello');var3.set('hello'); // No invalidationvar4.set(null);var4.set(null); // No invalidation// These always trigger invalidations:var5.set({ x: 1 });var5.set({ x: 1 }); // Invalidates! Objects are not deep-comparedvar6.set([1, 2, 3]);var6.set([1, 2, 3]); // Invalidates! Arrays are not deep-compared
The default check only considers primitive values equal:
const firstName = new ReactiveVar('John');const lastName = new ReactiveVar('Doe');// Computed value (not a ReactiveVar, but reactive)function fullName() { return `${firstName.get()} ${lastName.get()}`;}Tracker.autorun(() => { console.log('Full name:', fullName());});// Prints: Full name: John DoefirstName.set('Jane');// Prints: Full name: Jane Doe// Or create a ReactiveVar that depends on othersconst fullNameVar = new ReactiveVar('');Tracker.autorun(() => { fullNameVar.set(`${firstName.get()} ${lastName.get()}`);});
Since arrays are objects, you need to handle them specially:
// This doesn't work as expected:const items = new ReactiveVar([]);items.get().push('new item'); // No invalidation!// Correct approach:function addItem(item) { const current = items.get(); items.set([...current, item]); // Creates new array}function removeItem(index) { const current = items.get(); items.set(current.filter((_, i) => i !== index));}// Or use custom equality:const items = new ReactiveVar([], (a, b) => { // Always consider different (update on every set) return false;});
const myVar = new ReactiveVar(0);myVar.set(5);const value = myVar.get();// ✓ Scoped (not global)// ✓ Can hold any value (functions, DOM nodes, etc.)// ✓ Must be imported and passed around// ✓ Not persisted across hot code push// ✓ Custom equality functions
Session.set('myVar', 0);Session.set('myVar', 5);const value = Session.get('myVar');// ✓ Global (accessible anywhere)// ✓ Only EJSON-able values// ✓ Available everywhere by default// ✓ Persisted across hot code push// ✓ String keys can collide