Memahami public properties sebagai penyimpanan state antar request, tipe data yang didukung termasuk array dan model, serta wire:model dengan perilaku default deferred di v4, modifier .live, .debounce, .number, dan .lazy untuk mengontrol sinkronisasi client-server.

Setelah di episode 3 kalian membuat komponen Counter pertama dan melihat state berubah tanpa reload, sekarang kita masuk ke fondasi yang paling sering dipakai sepanjang series: public properties dan data binding. Hampir semua yang kalian lakukan dengan Livewire — form, filter, pencarian, CRUD — dimulai dari memahami dua hal ini dengan benar.
Perbedaan krusial dengan form HTML biasa: input HTML disimpan di browser, dan saat submit baru dikirim. Di Livewire, input langsung terhubung dengan property PHP melalui wire:model, sehingga state selalu bisa dibaca, divalidasi, dan dipakai kapan saja — termasuk untuk menampilkan feedback real-time.
Di Livewire, setiap public property menjadi bagian dari state komponen. Nilainya disimpan di server antar request (lewat snapshot), dan bisa di-render di view:
<?php
namespace App\Livewire;
use Livewire\Component;
class SearchBox extends Component
{
public string $query = '';
public int $limit = 10;
public array $categories = [];
public ?Post $activePost = null;
}Perhatikan: public string $query = '' memberi default value. Ini bukan sekadar kebiasaan baik — default menentukan tipe state dan melindungi dari error saat property kosong. Properties yang tidak dideklarasikan public (protected/private) tidak pernah menjadi bagian dari snapshot (lihat episode 2).
| Tipe | Contoh | Catatan |
|---|---|---|
| Scalar | string, int, float, bool | Paling umum untuk form & filter |
| Array | array $tags = [] | Berguna untuk checkbox grup |
| Eloquent model | public Post $post | Di-serialisasi & di-hydrate otomatis |
| Collection | public $items | Data list hasil query |
| Nullable | public ?Post $post = null | State opsional |
Model Eloquent boleh dijadikan property publik, dan Livewire akan menghubungkannya kembali saat request berikutnya. Namun ini juga menambah ukuran snapshot, jadi aturan praktisnya: simpan model hanya jika benar-benar diperlukan; untuk data turunan, pakai query ulang atau #[Computed] (episode 6).
wire:model adalah jembatan antara elemen form dan property PHP:
<div>
<input type="text" wire:model="query" placeholder="Cari artikel...">
<p>Kamu mengetik: {{ $query }}</p>
</div>Saat user mengetik, nilai input disinkronkan ke property $query di sisi server sesuai perilaku yang dikendalikan modifier (di bawah), dan setiap perubahan nilai memicu render ulang.
Ini perubahan paling penting dari v3 ke v4: di v4, wire:model default adalah deferred — input memperbarui property di sisi client secara instan, tetapi request ke server tidak dikirim setiap keystroke. State dikirim ke server saat blur, submit, atau aksi berikutnya.
<input type="text" wire:model="query"><input type="text" wire:model="query">Implikasinya besar: form dengan banyak field tidak lagi membanjiri server dengan request per karakter. Kalian memakai default ini untuk form biasa, dan memilih .live hanya saat benar-benar butuh feedback real-time (misalnya search-as-you-type).
Warning
Jika kalian pindah dari Livewire v3, ingat: di v3 wire:model mengirim request setiap keystroke dan .defer adalah opt-in. Di v4 perilakunya dibalik — default sudah deferred. Kode yang mengandalkan efek samping per-keystroke (misalnya update counter saat mengetik) harus ditambah .live agar tetap berjalan seperti sebelumnya.
.live — real-timeSinkronkan ke server setiap kali nilai berubah:
<input type="text" wire:model.live="query">Untuk pencarian yang merender hasil secara langsung, inilah pilihan yang tepat.
.debounce.500ms — real-time tapi dihematTunda pengiriman sampai user berhenti mengetik (dalam milidetik):
<input type="text" wire:model.live.debounce.500ms="query">.debounce mengurangi jumlah request saat user mengetik cepat, tanpa kehilangan nuansa real-time.
.number — konversi otomatis ke angka<input type="number" wire:model.number="limit">Tanpa .number, nilai input akan masuk sebagai string dan bisa merusak perbandingan numerik atau query.
.lazy — sinkron saat blur / changeKirim nilai hanya saat elemen kehilangan fokus (atau change untuk select/checkbox):
<input type="text" wire:model.lazy="query">.lazy berguna untuk field yang tidak perlu di-validasi atau diproses hingga user selesai mengisinya.
Modifier bisa digabung sesuai kebutuhan:
<input type="text" wire:model.live.debounce.300ms.trim="query">
<input type="number" wire:model.live.number="limit">trim menghapus spasi tepi; boolean mengonversi ke bool (untuk checkbox). Pilih modifier sesuai konteks: default deferred untuk form biasa, .live untuk pencarian, .debounce untuk request yang sering, .number/.boolean untuk konversi tipe.
null dan memicu error saat di-render atau divalidasi..live untuk semua field: boros request. Default deferred v4 ada untuk alasan itu..boolean: nilai checkbox masuk sebagai '1' (string) atau '0'; dengan .boolean menjadi true/false.Inti yang harus dibawa pulang:
wire:model menghubungkan input ke property; di v4 default deferred (kirim saat blur/submit)..live untuk real-time, .debounce.500ms untuk menghemat request, .lazy untuk blur, .number/.boolean untuk tipe..live berlebihan, dan tipe checkbox.Di episode 5 selanjutnya kita akan membahas actions & wire directives — memicu method dari view dengan wire:click, wire:submit, wire:change, mengirim parameter, serta wire:key, wire:ignore, dan wire:poll untuk mengontrol perilaku render dan polling. Pastikan kalian nyaman dengan wire:model, karena keduanya akan saling melengkapi di form interaktif. Sampai jumpa di episode 5!