Lifecycle & Initialization
WakaPAC provides three lifecycle hooks: init() runs immediately after component creation, ready() runs after all bindings are applied and the DOM is synchronized, and destroy() runs when the component is being removed.
Lifecycle Timeline
1. wakaPAC('#app', {...}) called
↓
2. Component abstraction created
↓
3. init() called (if defined)
↓
4. Bindings scanned and applied to DOM
↓
5. ready() called (if defined)
↓
6. Component is fully initialized
↓
... component lifetime ...
↓
7. Component removed from DOM
↓
8. destroy() called automatically (if defined)
↓
9. Framework cleanup (event listeners, timers, etc.)
The init() Hook
Called immediately after component creation, before bindings are applied to the DOM.
<div id="app">
<div data-pac-bind="if: loading">Loading...</div>
<div data-pac-bind="if: user">Welcome, {{user.name}}!</div>
</div>
<script>
wakaPAC('#app', {
user: null,
loading: true,
async init() {
const response = await fetch('/api/user/current');
this.user = await response.json();
this.loading = false;
}
});
</script>
The ready() Hook
Called after all bindings are applied and the DOM is fully synchronized with your data.
<div id="app">
<canvas id="chart"></canvas>
<button data-pac-bind="click: randomizeData">Randomize</button>
</div>
<script>
wakaPAC('#app', {
salesData: [65, 59, 80, 81, 56, 55, 40],
_chart: null,
ready() {
const ctx = document.getElementById('chart').getContext('2d');
this._chart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
datasets: [{ label: 'Sales', data: this.salesData }]
}
});
},
randomizeData() {
this.salesData = this.salesData.map(() => Math.floor(Math.random() * 100));
this._chart.data.datasets[0].data = this.salesData;
this._chart.update();
}
});
</script>
The destroy() Hook
Called when the component is being removed from the DOM, before framework cleanup.
<div id="ticker">Price: ${{price}}</div>
<script>
wakaPAC('#ticker', {
price: 0,
_ws: null,
init() {
this._ws = new WebSocket('wss://api.example.com/stocks');
this._ws.onmessage = (e) => {
this.price = JSON.parse(e.data).price;
};
},
destroy() {
if (this._ws) {
this._ws.close();
this._ws = null;
}
}
});
</script>
Quick Reference
| Hook | When Called | Common Use Cases |
|---|---|---|
init() |
After creation, before bindings | API calls, data loading, state initialization |
ready() |
After bindings applied | DOM manipulation, third-party libraries |
destroy() |
Before removal (automatic) | Cleanup timers, close connections |
Important Notes
- DOM access: Never access DOM elements in
init()- they don't exist yet. Useready()instead. - Automatic cleanup: Never call
destroy()manually. Simply remove the component's DOM element and the framework handles cleanup automatically. - Private properties: Use underscore prefix (e.g.,
_chart) for third-party library instances to prevent reactivity overhead. - Mirror init/destroy: Resources created in
init()should be cleaned up indestroy(). - Child components: Automatically destroyed when their parent is removed from the DOM.