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. Use ready() 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 in destroy().
  • Child components: Automatically destroyed when their parent is removed from the DOM.