DEV Community

hbgl
hbgl

Posted on • Edited on

1

Laravel shorts - Blade component gotcha

Update 2021-10-22
An issue has been created on GitHub: https://github.com/laravel/framework/issues/39232

And a fix has been merged:
https://github.com/laravel/framework/pull/39319


Blade components are a great tool for structuring your view templates into small reusable pieces. But while working with them, I stumbled upon a gotcha that I think you should know about. First, let's take a look at this anonymous component:

post-title.blade.php

@props(['post'])
<h1 {{ $attributes }}>{{ $post->title }}</h1>
Enter fullscreen mode Exit fullscreen mode

And here is how it is used in, say, a post list page:

@foreach ($posts as $post)
  <x-post-title :post="$post" />
@endforeach
Enter fullscreen mode Exit fullscreen mode

In this example, the posts are Eloquent models that were previously loaded from the database. Now, if you run this code, you will notice nothing strange in particular. Everything works as intended. However, if you dig a little deeper, you will find some unexpected behavior:

Every time the component is instantiated, the post model is being serialized to JSON.

The cause for this behavior lies in the way the Blade component compiler processes attributes inside the sanitizeComponentAttribute function.

CompilesComponents.php

/**
 * Sanitize the given component attribute value.
 *
 * @param  mixed  $value
 * @return mixed
 */
public static function sanitizeComponentAttribute($value)
{
    return is_string($value) ||
           (is_object($value) && ! $value instanceof ComponentAttributeBag && method_exists($value, '__toString'))
                    ? e($value)
                    : $value;
}
Enter fullscreen mode Exit fullscreen mode

Basically, any object that implements a __toString function will be converted to a string. In the case of an Eloquent model, this will convert it to JSON. Depending on how large your model is and how often the component is used, this will waste a significant amount of resources on constructing JSON strings that are never used.

Solution: Use class based components

Instead of an anonymous component, use a class based component and add your props to the constructor arguments. After you do that, your objects will no longer be converted to strings.

<?php

namespace App\View\Components;

use Illuminate\View\Component;

class PostTitle extends Component
{
    public $post;

    public function __construct($post)
    {
        $this->post = $post;
    }

    public function render()
    {
        return view('components.post-title');
    }
}
Enter fullscreen mode Exit fullscreen mode

The post Laravel shorts – Blade component gotcha appeared first on hbgl.

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay