Membangun komunikasi antar komponen Livewire: mengirim event dengan $this->dispatch, mendengarkan event dengan #[On], event berparameter, serta pola parent-child dengan reactive props untuk menciptakan komponen yang terpisah tapi saling berkolaborasi.

Sejauh ini semua contoh memakai satu komponen mandiri. Di aplikasi nyata, satu halaman berisi banyak komponen — header, sidebar, form, daftar data — yang saling memengaruhi. Menghapus sebuah item di daftar harus memperbarui badge jumlah; menyimpan form harus menutup modal di komponen lain.
Di episode ini kita belajar events: mekanisme resmi agar komponen saling berkomunikasi tanpa saling tahu detail internal satu sama lain. Ini adalah konsep decoupling — komponen berbicara lewat pesan, bukan lewat memanggil kode satu sama lain secara langsung.
Komponen mengirim event lewat method dispatch:
$this->dispatch('post-created');Event ini bisa didengar oleh komponen lain di halaman yang sama. Saat event diterima, listener dijalankan dan komponen penerima merender ulang.
$this->dispatch('post-created', postId: $post->id);Parameter bernama (postId:) membuat payload lebih ekspresif dan tidak mudah salah urut. Di sisi penerima, parameter ini muncul sebagai argumen method listener.
Secara default event disiarkan ke seluruh komponen di halaman. Kalian bisa mempersempit cakupan:
$this->dispatch('post-created')->self(); // hanya komponen ini
$this->dispatch('post-created')->to(StatsPanel::class); // komponen spesifik
$this->dispatch('post-created'); // semua komponenListener dideklarasikan dengan attribute #[On]:
<?php
namespace App\Livewire;
use Livewire\Attributes\On;
use Livewire\Component;
class StatsPanel extends Component
{
public int $postCount = 0;
public function mount()
{
$this->postCount = Post::count();
}
#[On('post-created')]
public function refreshStats(int $postId)
{
$this->postCount = Post::count();
}
}Saat komponen lain mengirim post-created, method refreshStats() dijalankan dan $postCount diperbarui. Perhatikan bahwa method-nya tidak perlu public — #[On] cukup untuk mendaftarkannya sebagai listener.
#[On] mendukung wildcard untuk mendengar banyak event sekaligus:
#[On('post.*')]
public function handlePostEvent(string $event, array $params)
{
// $event berisi nama event penuh, misal "post.created"
// $params berisi parameter yang dikirim
}Ini berguna saat banyak komponen mengirim varian event post.created, post.updated, post.deleted dan kalian ingin menanganinya dengan satu listener.
Tip
Event adalah solusi saat dua komponen tidak punya hubungan parent-child atau saat hubungannya terlalu dalam untuk ditembus prop demi prop. Untuk komponen yang memang disusun bertingkat (parent berisi child), reactive props sering lebih sederhana — lihat bagian berikutnya.
Saat komponen memang disusun berpasangan (parent merender child), ada dua pola:
Parent mengirim nilai saat render, child menerimanya di mount():
<livewire:post-count :count="$posts->count()" />public function mount(int $count)
{
$this->count = $count;
}Pola ini statis: jika $count berubah di parent, child tidak otomatis ikut berubah.
Dengan attribute #[Reactive], perubahan nilai prop di parent langsung memicu render ulang child:
<?php
namespace App\Livewire;
use Livewire\Attributes\Reactive;
use Livewire\Component;
class PostCount extends Component
{
#[Reactive]
public int $count = 0;
public function render()
{
return view('livewire.post-count');
}
}<div>
<livewire:post-count :count="$posts->count()" />
<button wire:click="addPost">Tambah post</button>
</div>Setiap kali parent mengubah data yang memengaruhi $posts->count(), child PostCount ikut merender ulang secara otomatis. Kombinasi ini adalah pola paling rapi untuk widget statistik, badge jumlah, atau daftar yang saling bergantung.
Mari gabungkan semuanya dalam satu skenario:
public function save()
{
$post = Post::create([
'title' => $this->title,
]);
$this->dispatch('post-created', postId: $post->id);
$this->reset('title');
}CreatePost mengirim post-created setelah menyimpan.StatsPanel mendengarnya dan memperbarui jumlah.->self() yang membatasi ke komponen pengirim.postId: $post->id) dan sesuaikan nama argumen di method listener.Inti yang harus dibawa pulang:
$this->dispatch('nama-event', param: nilai); dengarkan dengan #[On('nama-event')].->self(), ->to(Class::class), atau broadcast default ke semua.#[On('post.*')] untuk wildcard; method listener menerima $event dan $params.#[Reactive] (live, ikut render ulang).Di episode 8 selanjutnya kita akan membahas rendering & layout — menyusun layout dengan komponen <x-layout>, sectioning untuk memecah halaman, dynamic page titles, dan modularisasi UI (header, sidebar, content) sebagai komponen. Sampai jumpa di episode 8!