WakaPAC's reactivity system automatically synchronizes your data with the DOM. Change a property, and the UI updates - no manual DOM manipulation required.
When you create a WakaPAC component, all properties in your abstraction object become reactive:
wakaPAC('#app', {
count: 0,
increment() {
this.count++; // Change is detected, DOM updates scheduled
}
});
WakaPAC's reactivity engine:
WakaPAC recursively wraps nested objects in proxies, making changes at any depth reactive:
<div id="app">
<p>{{user.name}}</p>
<p>Theme: {{user.preferences.theme}}</p>
<button data-pac-bind="click: changeTheme">Toggle Theme</button>
</div>
<script>
wakaPAC('#app', {
user: {
name: 'John',
preferences: {
theme: 'dark'
}
},
changeTheme() {
// Deep property changes trigger reactivity
this.user.preferences.theme =
this.user.preferences.theme === 'dark' ? 'light' : 'dark';
}
});
</script>
WakaPAC intercepts array mutator methods (push, pop, splice, shift, unshift, sort, reverse) to trigger updates automatically:
<div id="app">
<ul data-pac-bind="foreach: todos" data-pac-item="todo">
<li>{{todo.text}} (Item {{$index}})</li>
</ul>
<button data-pac-bind="click: addTodo">Add Todo</button>
</div>
<script>
wakaPAC('#app', {
todos: [
{ text: 'Learn WakaPAC', completed: false },
{ text: 'Build an app', completed: false }
],
addTodo() {
// Array mutations automatically trigger re-render of the list
this.todos.push({
text: 'New todo',
completed: false
});
}
});
</script>
Objects stored in arrays are also wrapped in proxies, making their property changes reactive:
<div id="app">
<div data-pac-bind="foreach: todos" data-pac-item="todo" >
<input type="checkbox" data-pac-bind="checked: todo.completed">
<span>{{todo.text}} (Item {{$index}})</span>
<button data-pac-bind="click: toggleTodo">Toggle</button>
</div>
</div>
<script>
wakaPAC('#app', {
todos: [
{ text: 'Task 1', completed: false },
{ text: 'Task 2', completed: false }
],
toggleTodo(todo, index) {
// Modifying object properties inside arrays triggers reactivity
todo.completed = !todo.completed;
}
});
</script>
Within a foreach loop, WakaPAC provides the special variable $index containing the current iteration index (0-based). The $ prefix distinguishes it from user-defined properties, preventing naming conflicts.
You can customize the index variable name using the data-pac-index attribute:
<div data-pac-bind="foreach: items" data-pac-index="i">
<span>Item {{i}}: {{item}}</span>
</div>
WakaPAC batches multiple changes into a single DOM update cycle using microtasks. If you change the same property multiple times synchronously, only the final value triggers a DOM update:
this.count = 1;
this.count = 2;
this.count = 3;
// DOM updates once with value 3, not three times
Only elements that actually reference a changed property are updated. If you have 100 elements but only one uses {{count}}, changing count updates only that element.
If an element is queued for update multiple times before the microtask executes (e.g., from changes to different properties it depends on), it only updates once with all new values.
Properties added to an object after proxy creation are not automatically reactive. To add reactive properties dynamically, reassign the entire object:
// ❌ This won't be reactive
this.user.newProperty = 'value';
// ✅ This will be reactive
this.user = { ...this.user, newProperty: 'value' };
Direct array index assignment is reactive, but sparse array assignments may not behave as expected:
// ✅ Reactive
this.todos[0] = newTodo;
// ⚠️ Creates sparse array, may not update correctly
this.todos[100] = newTodo;
Use push(), splice(), or reassign the array for complex operations.
When passing primitive values to child components or functions, changes to the original won't affect the copy:
let count = this.count; // count is now a copy
count++; // this.count is unchanged
Always modify properties directly on this to maintain reactivity.