Skip to main content

Black Friday 2025! Only until December 1st: coupon FRIDAY25 for 40% off Yearly/Lifetime membership!

Read more here

Parent-Child Components and Reactive Properties

Premium
4 min read

In this lesson, let's see how Livewire's parent and child components can communicate with each other.


Initial Components

For this example, we will have two Livewire components. One for listing todos and the second for showing info about todos.

php artisan make:livewire TodosList
php artisan make:livewire TodoInfo

app/Livewire/TodosList.php:

use App\Models\Todo;
use Illuminate\Support\Collection;
use Illuminate\Contracts\View\View;
 
class TodosList extends Component
{
public Collection $todos;
public ?Todo $selected;
 
public function mount(): void
{
$this->todos = Todo::all();
 
$this->selected = $this->todos->first();
}
 
public function select(Todo $todo): void
{
$this->selected = $todo;
}
 
public function render(): View
{
return view('livewire.todos-list');
}
}

resources/views/livewire/todos-list.blade.php:

<div class="py-12">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white dark:bg-gray-800 overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-6 text-gray-900 dark:text-gray-100 space-y-6">
 
@if($selected)
<livewire:todo-info :todo="$selected" />
@endif
 
@foreach($todos as $todo)
<div wire:click="select({{ $todo->id }})" @class(['bg-slate-100 px-3 py-2', 'border border-slate-800' => $todo == $selected])>
{{ $todo->title }}
</div>
@endforeach
</div>
</div>
</div>
</div>

app/Livewire/TodoInfo.php:

use App\Models\Todo;
use Livewire\Component;
use Illuminate\Contracts\View\View;
 
class TodoInfo extends Component
{
public Todo $todo;
 
public function render(): View
{
return view('livewire.todo-info');
}
}

resources/views/livewire/todo-info.blade.php:

<div>
<div><span class="text-gray-500">Title:</span> {{ $todo->title }}</div>
<div><span class="text-gray-500">Body:</span> {{ $todo->body }}</div>
<div><span class="text-gray-500">Due at:</span> {{ $todo->due_at }}</div>
</div>

After adding some data to the todos table, we will have a list of todos.

todos list


Making Property Reactive

Now we have a simple list of todos and the first one as selected. If we try to select another todo, it gets selected, but the information about it doesn't update.

This is because Livewire tries to send as minimal requests to the server as possible. In this case, we need to make a child component property reactive. We must add...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (29 h 14 min)

You also get:

54 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

M
Meesterdaaf ✓ Link copied!

This does not work. After adding the #[Reactive] attribute i get the following error message: Cannot mutate reactive prop [userstory] in component: [criteria-check]

PB
Pablo Beca ✓ Link copied!

Todo Migration:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    /**
     * Run the migrations.
     */
    public function up(): void
    {
        Schema::create('todos', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->text('body')->nullable();
            $table->dateTime('due_at')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('todos');
    }
};

Todo Model

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class Todo extends Model
{
    use HasFactory;

    protected $fillable = ['title', 'body', 'due_at'];

}

Route

Route::get('todos', \App\Livewire\TodosList::class)->name('todos');

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.