earmsby's avatar

DRY code in Livewire component

I have two different livewire components that do slightly different things. However, a few properties and methods are exactly the same between the two components. I'd like to make my code more efficient by separating out the shared properties and methods into it's own class but I'm not quite sure where to start with that. Do I create a third livewire component for this or is there a better way. Hope my question makes sense.

0 likes
6 replies
LaryAI's avatar
Level 58

Great question! In situations like this, the best approach is to extract the shared properties and methods into a PHP trait. Traits allow you to reuse code in multiple classes (including Livewire components) without inheritance.

Here’s how you can do it:

  1. Create a Trait

Create a new file, for example, app/Http/Livewire/Concerns/HasSharedLogic.php:

<?php

namespace App\Http\Livewire\Concerns;

trait HasSharedLogic
{
    public $sharedProperty;

    public function sharedMethod()
    {
        // Shared logic here
    }
}
  1. Use the Trait in Your Components

In both of your Livewire components, use the trait:

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Http\Livewire\Concerns\HasSharedLogic;

class FirstComponent extends Component
{
    use HasSharedLogic;

    // Component-specific logic here
}

And in your second component:

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Http\Livewire\Concerns\HasSharedLogic;

class SecondComponent extends Component
{
    use HasSharedLogic;

    // Component-specific logic here
}

Notes:

  • You do not need to create a third Livewire component for shared logic.
  • Traits are the standard way to DRY up code in Livewire components.
  • If you have shared validation rules or listeners, you can also include those in the trait.

Summary:
Extract shared logic into a trait and use that trait in any Livewire component that needs it. This keeps your code DRY and maintainable!

1 like
martinbean's avatar

I have two different livewire components that do slightly different things. However, a few properties and methods are exactly the same between the two components.

@earmsby If that’s the case, then move those common properties and methods to a parent class, and have your two Livewire components extend that parent class:

abstract class ManageArticle extends Component
{
    // Common properties and methods here...
}
class CreateArticle extends ManageArticle
{
    // Create-specific properties and methods here...

    public function render()
    {
        return view('livewire.create-article');
    }
}
class UpdateArticle extends ManageArticle
{
    // Update-specific properties and methods here...

    public function render()
    {
        return view('livewire.edit-article');
    }
}
earmsby's avatar

@martinbean is there a benefit to doing it this way as opposed to using a trait as described in the AI solution?

martinbean's avatar
Level 80

@earmsby Because it’s a problem solved by inheritance (a common parent class) and not composition (a trait).

You wanted to de-duplicate common properties and methods that two components required. You would use a trait if you had some logic you wanted to share with multiple, unrelated components where extending a common parent class would not be possible.

earmsby's avatar

@martinbean, Hmmm makes some sense. I'll try that approach as well (not at the same time!)

1 like

Please or to participate in this conversation.