Do Not Render a Laravel Component

There have been many times when I was building a Laravel View Component and only wanted to render the HTML based on some logic.

In the past, I added a Blade @if block to the actual component view code. It is clear when looking at the HTML and achieves what I need, but it isn't very nice. For example, I only wanted the component to render if the items collection is not empty…

@if ($items->isNotEmpty())
// the actual HTML we care about.
@endif

In more recent projects, I moved the logic to the component class. I put the if logic inside the render() method. If the items collection is empty, then just render an empty string. Again, this worked fine, but it seemed wrong to combine this logic inside which view should be used. It also muddled the method to support both View and string return types.

<?php

namespace App\View\Components;

use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection;
use Illuminate\View\Component;

class YourComponent extends Component
{
    public Collection $items;

    public function __construct()
    {
        $this->items = Collection::make();
    }
    
    public function render(): View|string
    {
	    if ($this->items->isEmpty()) {
			return '';
	    }
	    
        return view('components.your-component');
    }
}

Then I stumbled on the shouldRender() method in the extended base class… This is the exact correct place for this functionality. By default this simply returns true, but we can override this logic in our class. Now the component should render if the items collection is not empty. The class now looks like this;

<?php

namespace App\View\Components;

use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection;
use Illuminate\View\Component;

class YourComponent extends Component
{
    public Collection $items;

    public function __construct()
    {
        $this->items = Collection::make();
    }
    
    public function render(): View
    {
        return view('components.your-component');
    }
    
    public function shouldRender(): bool
    {
        return $this->items->isNotEmpty();
    }
}

The only reference to shouldRender() in the documentation is under “reserved keywords” so you might have missed this little feature.