Sharing State and Events Between Parent and Child Components in Livewire Laravel


Laravel Livewire is an excellent framework for building dynamic, reactive interfaces using Laravel. One of the key aspects of building complex applications is managing the state and events between parent and child components effectively. This article will guide you through various techniques to share state and events between parent and child components in Livewire.


Understanding Parent and Child Components


In Livewire, you can break down your application into small, manageable components. A parent component can contain one or more child components, each responsible for a specific piece of functionality. Sharing state and events between these components is crucial for building cohesive and interactive interfaces.


Creating Parent and Child Components


Let's start by creating a parent component and a child component.


1. Create Parent Component


   php artisan make:livewire ParentComponent


   // app/Http/Livewire/ParentComponent.php

   namespace App\Http\Livewire;


   use Livewire\Component;


   class ParentComponent extends Component

   {

       public $message = 'Hello from Parent';


       public function render()

       {

           return view('livewire.parent-component');

       }

   }


   <!-- resources/views/livewire/parent-component.blade.php -->

   <div>

       <h1>Parent Component</h1>

       <livewire:child-component :message="$message" />

   </div>


2. Create Child Component


   php artisan make:livewire ChildComponent


   // app/Http/Livewire/ChildComponent.php

   namespace App\Http\Livewire;


   use Livewire\Component;


   class ChildComponent extends Component

   {

       public $message;


       public function mount($message)

       {

           $this->message = $message;

       }


       public function render()

       {

           return view('livewire.child-component');

       }

   }


   <!-- resources/views/livewire/child-component.blade.php -->

   <div>

       <h2>Child Component</h2>

       <p>{{ $message }}</p>

   </div>


Sharing State Between Components


There are several ways to share state between parent and child components in Livewire.


1. Passing Data via Props


   In the example above, we passed the `message` state from the parent component to the child component using props.


   <livewire:child-component :message="$message" />


2. Two-Way Data Binding


   Livewire supports two-way data binding, allowing child components to update the parent component's state. To achieve this, use wire:model in the parent component.


   // ParentComponent.php

   class ParentComponent extends Component

   {

       public $message = 'Hello from Parent';


       public function render()

       {

           return view('livewire.parent-component');

       }

   }


   <!-- parent-component.blade.php -->

   <div>

       <h1>Parent Component</h1>

       <input wire:model="message" type="text">

       <livewire:child-component :message="$message" />

   </div>


   // ChildComponent.php

   class ChildComponent extends Component

   {

       public $message;


       public function mount($message)

       {

           $this->message = $message;

       }


       public function updatedMessage($value)

       {

           $this->emit('messageUpdated', $value);

       }


       public function render()

       {

           return view('livewire.child-component');

       }

   }


   <!-- child-component.blade.php -->

   <div>

       <h2>Child Component</h2>

       <input wire:model="message" type="text">

       <p>{{ $message }}</p>

   </div>


3. Event Emission and Listening


   Use Livewire's event system to emit events from the child component and listen to them in the parent component.


   // ParentComponent.php

   class ParentComponent extends Component

   {

       public $message = 'Hello from Parent';


       protected $listeners = ['messageUpdated' => 'updateMessage'];


       public function updateMessage($message)

       {

           $this->message = $message;

       }


       public function render()

       {

           return view('livewire.parent-component');

       }

   }


   <!-- parent-component.blade.php -->

   <div>

       <h1>Parent Component</h1>

       <p>{{ $message }}</p>

       <livewire:child-component />

   </div>


   // ChildComponent.php

   class ChildComponent extends Component

   {

       public $message = 'Hello from Child';


       public function updateParent()

       {

           $this->emit('messageUpdated', $this->message);

       }


       public function render()

       {

           return view('livewire.child-component');

       }

   }


   <!-- child-component.blade.php -->

   <div>

       <h2>Child Component</h2>

       <input wire:model="message" type="text">

       <button wire:click="updateParent">Update Parent</button>

       <p>{{ $message }}</p>

   </div>



Managing state and events between parent and child components in Livewire is straightforward and flexible. By passing data via props, leveraging two-way data binding, and using Livewire's event system, you can build complex, interactive interfaces with ease. Integrating these techniques ensures your components remain decoupled and maintainable, enabling you to create dynamic and responsive applications with Laravel Livewire.