Belajar Livewire - Lifecycle Hooks & Computed Properties
Episode 6 of 23

Belajar Livewire - Lifecycle Hooks & Computed Properties

Memahami siklus hidup komponen Livewire: mount, boot, hydrate, updating, updated, dan render, termasuk hook per-action, serta computed properties dengan #[Computed] untuk nilai turunan yang di-cache per request.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 5 kalian bisa memicu action dari view, sekarang kita masuk ke bagian yang membuat Livewire bisa diandalkan di aplikasi nyata: kapan kode dijalankan. Setiap request Livewire menjalani urutan siklus hidup yang tetap, dan dengan memahami urutan ini kalian bisa menentukan titik yang tepat untuk inisialisasi, validasi, dan pembersihan.

Selain itu kita akan membahas computed properties — salah satu fitur paling berdampak pada performa. Banyak developer pemula menyimpan hasil query di public property; padahal hasil tersebut bisa dihitung ulang otomatis dan di-cache per request dengan #[Computed], tanpa membebani payload snapshot.

Urutan Siklus Hidup

Setiap kali Livewire memproses request (baik initial load maupun interaksi), komponen menjalani urutan hook berikut:

100%

boot dan booted

Dijalankan pertama kali, sebelum apa pun — termasuk sebelum state di-hydrate. Cocok untuk mengatur dependensi global yang tidak bergantung pada state:

Hook boot
public function boot()
{
    // berjalan di setiap request, paling awal
}

hydrate dan hydrated

Dijalankan setelah state dari request sebelumnya dipulihkan ke komponen. Berguna untuk menyiapkan ulang sesuatu yang tidak ter-serialisasi (misalnya repository atau service):

Hook hydrate
public function hydrate()
{
    $this->repo = app(PostRepository::class);
}

mount

Dijalankan hanya sekali, saat komponen pertama kali dirender (bukan pada request interaksi berikutnya). Inilah tempat untuk inisialisasi state dan query awal:

Hook mount dengan parameter
public function mount(?Post $post = null)
{
    $this->post = $post;
    $this->title = $post?->title ?? '';
}

mount() bisa menerima parameter — nilainya dikirim dari tempat komponen dirender:

Kirim parameter ke mount
<livewire:post-form :post="$post" />

updating / updated

Dipanggil setiap kali public property diubah (lewat wire:model atau assignment di kode). Ada dua level: hook umum yang menerima nama property, dan hook spesifik per property:

Hook updating dan updated
public function updating($property, $value)
{
    // sebelum semua property berubah
}
 
public function updated($property, $value)
{
    // setelah semua property berubah
}
 
public function updatingQuery($value)
{
    // khusus property `query`, sebelum berubah
}
 
public function updatedQuery($value)
{
    // khusus property `query`, setelah berubah
    // tempat ideal untuk memproses pencarian
}

updatedQuery() adalah pola paling umum untuk search-as-you-type: saat user mengetik di input wire:model.live, hook ini menjalankan query dan menyimpan hasilnya.

Hook per-action

Setiap action juga memiliki hook call dan called:

Hook per action
public function callSave()
{
    // sebelum action save()
}
 
public function calledSave()
{
    // setelah action save() selesai
}

render

Bagian terakhir dari setiap siklus — memproduksi view. Default-nya sudah otomatis (Laravel menebak nama view dari nama komponen), jadi biasanya tidak perlu di-override:

Override render
public function render()
{
    return view('livewire.dashboard', [
        'stats' => $this->stats,
    ]);
}

Computed Properties dengan #[Computed]

Masalah klasik: sebuah nilai dihitung dari beberapa property, dan kalian ingin memakainya di view tanpa menyimpannya sebagai state.

Tanpa computed (boros & berulang)
public function posts()
{
    return Post::where('status', 'published')
        ->orderBy('published_at', 'desc')
        ->limit(10)
        ->get();
}

Jika posts() dipanggil beberapa kali di view, query dieksekusi berulang. Solusinya: computed property dengan attribute #[Computed]. Nilainya dihitung sekali per request dan di-cache otomatis:

Computed property
<?php
 
namespace App\Livewire;
 
use Livewire\Attributes\Computed;
use Livewire\Component;
use App\Models\Post;
 
class Dashboard extends Component
{
    #[Computed]
    public function posts()
    {
        return Post::where('status', 'published')
            ->orderBy('published_at', 'desc')
            ->limit(10)
            ->get();
    }
}
Akses di view
<div>
    @foreach ($this->posts as $post)
        <p>{{ $post->title }}</p>
    @endforeach
 
    <p>Total: {{ $this->posts->count() }}</p>
</div>

Perhatikan aksesnya: $this->posts di Blade — sama seperti property biasa, padahal ia method. Inilah keunggulan utamanya:

  • Cache per request: dipanggil berkali-kali, dieksekusi sekali.
  • Bukan state: tidak ikut dalam snapshot, sehingga payload tetap kecil.
  • Selalu segar: dihitung ulang setiap request, jadi tidak pernah basi seperti public property yang lupa di-update.

Tip

Aturan praktisnya: jika sebuah nilai bisa diturunkan dari state yang sudah ada (query, kalkulasi, transformasi), jadikan #[Computed], bukan public property. Public property hanya untuk nilai yang dimasukkan user atau berubah lewat aksi — sisanya computed.

Computed dengan parameter

#[Computed] juga bisa menerima parameter, dan cache-nya di-key per kombinasi argumen:

Computed dengan parameter
#[Computed]
public function commentsFor(int $postId)
{
    return Comment::where('post_id', $postId)->latest()->get();
}

Di v4, cache TTL computed bisa dikonfigurasi eksplisit untuk data yang jarang berubah — kita bedah bersama caching di episode 21.

Pitfall Umum

  • Query di mount() yang harusnya diperbarui: state di mount() hanya dijalankan sekali. Jika nilainya harus berubah mengikuti input, pindahkan ke updated* hook atau jadikan computed.
  • Menyimpan hasil query di public property: menambah payload dan berisiko basi. Pakai #[Computed].
  • Mengubah property di hook updating secara rekursif: memodifikasi property yang sama di hook ini bisa memicu loop. Lakukan modifikasi di updated bila perlu.
  • Computed yang bergantung pada properti non-publik: cache tidak otomatis invalidasi jika dependensinya bukan state.

Penutup

Inti yang harus dibawa pulang:

  • Urutan siklus hidup: boothydrateupdating/updated → action → render; mount() hanya sekali.
  • mount() untuk inisialisasi; updatedQuery() untuk pencarian real-time; call*/called* untuk per-action.
  • #[Computed] = nilai turunan yang di-cache per request, tidak masuk snapshot.
  • Pilih antara public property (state) vs computed (turunan) dengan sadar.

Di episode 7 selanjutnya kita akan membahas events & komunikasi antar komponen$this->dispatch() untuk mengirim event, #[On] untuk mendengarkan, event dengan parameter, serta komunikasi parent-child dengan reactive props. Ini akan menjadi dasar untuk memecah aplikasi besar menjadi komponen-komponen yang saling berkolaborasi. Sampai jumpa di episode 7!

Belajar Livewire - Lifecycle Hooks & Computed Properties | Belajar Livewire