ライフサイクルのフック
Livewireは、コンポーネントのライフサイクルの特定の時点でコードを実行できるようにするための、さまざまなライフサイクルフックを提供しています。これらのフックを使用すると、コンポーネントの初期化、プロパティの更新、テンプレートのレンダーなど、特定のイベントの前後にアクションを実行できます。Livewire provides a variety of lifecycle hooks that allow you to execute code at specific points during a component's lifecycle. These hooks enable you to perform actions before or after particular events, such as initializing the component, updating properties, or rendering the template.
利用可能なすべてのコンポーネント・ライフサイクル・フックの一覧を以下に示します。Here's a list of all the available component lifecycle hooks:
フックメソッドHook Method | 説明Description |
---|---|
mount() mount() |
コンポーネントを作成したときに呼び出すCalled when a component is created |
hydrate() hydrate() |
後続のリクエストの開始時に、コンポーネントを再度ハイドレートするときに呼び出すCalled when a component is re-hydrated at the beginning of a subsequent request |
boot() boot() |
すべてのリクエストの開始時に呼び出す。初回とそれ以降の両方で呼び出すCalled at the beginning of every request. Both initial, and subsequent |
updating() updating() |
コンポーネントのプロパティを更新する前に呼び出すCalled before updating a component property |
updated() updated() |
プロパティを更新した後に呼び出すCalled after updating a property |
rendering() rendering() |
render() を呼び出す前に呼び出すCalled before render() is called |
rendered() rendered() |
render() を呼び出した後に呼び出すCalled after render() is called |
dehydrate() dehydrate() |
すべてのコンポーネントリクエストの最後に呼び出すCalled at the end of every component request |
exception($e, $stopPropagation) exception($e, $stopPropagation) |
例外を投げたときに呼び出すCalled when an exception is thrown |
MountMount
標準のPHPクラスでは、コンストラクタ(__construct()
)は外部パラメータを受け取り、オブジェクトの状態を初期化します。しかし、Livewireでは、mount()
メソッドを使用してパラメータを受け取り、コンポーネントの状態を初期化します。In a standard PHP class, a constructor (__construct()
) takes in outside parameters and initializes the object's state. However, in Livewire, you use the mount()
method for accepting parameters and initializing the state of your component.
Livewireコンポーネントは、後続のネットワーク・リクエストで再構築するため、__construct()
を使用しません。最初に作成されたときにコンポーネントを一度だけ初期化したいのです。Livewire components don't use __construct()
because Livewire components are re-constructed on subsequent network requests, and we only want to initialize the component once when it is first created.
以下に、mount()
メソッドを使用して、UpdateProfile
コンポーネントのname
とemail
プロパティを初期化する例を示します。Here's an example of using the mount()
method to initialize the name
and email
properties of an UpdateProfile
component:
use Illuminate\Support\Facades\Auth;
use Livewire\Component;
class UpdateProfile extends Component
{
public $name;
public $email;
public function mount()
{
$this->name = Auth::user()->name;
$this->email = Auth::user()->email;
}
// …
}
前述のように、mount()
メソッドは、コンポーネントへ渡すデータをメソッドパラメータとして受け取ります。As mentioned earlier, the mount()
method receives data passed into the component as method parameters:
use Livewire\Component;
use App\Models\Post;
class UpdatePost extends Component
{
public $title;
public $content;
public function mount(Post $post)
{
$this->title = $post->title;
$this->content = $post->content;
}
// …
}
Laravelのサービス・コンテナにより依存関係を解決できます。[!tip] You can use dependency injection with all hook methods Livewire allows you to resolve dependencies out of Laravel's service container[https://laravel.com/docs/container#automatic-injection] by type-hinting method parameters on lifecycle hooks.
Tip: すべてのフック・メソッドで依存性注入を使用できます: Livewireでは、ライフサイクル・フックのメソッド・パラメータに型ヒントを付けることで、
mount()
メソッドは、Livewireの使用において重要な部分です。以下のドキュメントでは、一般的なタスクを実行するためにmount()
メソッドを使用する例をさらに示してます。The mount()
method is a crucial part of using Livewire. The following documentation provides further examples of using the mount()
method to accomplish common tasks:
- プロパティの初期化Initializing properties[/docs/properties#initializing-properties]
- 親コンポーネントからデータを受け取るReceiving data from parent components[/docs/nesting#passing-props-to-children]
- ルート・パラメータへのアクセスAccessing route parameters[/docs/components#accessing-route-parameters]
BootBoot
mount()
は非常に役立ちますが、コンポーネントのライフサイクルごとに1回しか実行されません。特定のコンポーネントに対し、サーバへのすべてのリクエストの開始時にロジックを実行したい場合もあります。As helpful as mount()
is, it only runs once per component lifecycle, and you may want to run logic at the beginning of every single request to the server for a given component.
こうした場合、Livewireは、コンポーネントクラスが起動されるたび(初期化時と後続のリクエストの両方で)実行するコンポーネントのセットアップコードを記述できるboot()
メソッドを提供しています。For these cases, Livewire provides a boot()
method where you can write component setup code that you intend to run every single time the component class is booted: both on initialization and on subsequent requests.
boot()
メソッドは、リクエスト間で永続化しないprotectedプロパティの初期化などに役立ちます。以下は、protectedプロパティをEloquentモデルとして初期化する例です。The boot()
method can be useful for things like initializing protected properties, which are not persisted between requests. Below is an example of initializing a protected property as an Eloquent model:
use Livewire\Attributes\Locked;
use Livewire\Component;
use App\Models\Post;
class ShowPost extends Component
{
#[Locked]
public $postId = 1;
protected Post $post;
public function boot() // [tl! highlight:3]
{
$this->post = Post::find($this->postId);
}
// …
}
この手法を使用し、Livewireコンポーネントでコンポーネントプロパティの初期化を完全にコントロールできます。You can use this technique to have complete control over initializing a component property in your Livewire component.
Livewireの算出プロパティを使用してこのユースケースを解決する方が適していることがよくあります。[!tip] Most of the time, you can use a computed property instead The technique used above is powerful; however, it's often better to use Livewire's computed properties[/docs/computed-properties] to solve this use case.
Tip: ほとんどの場合、算出プロパティを代わりに使用できます: 上記の手法は強力ですが、
Warning! 常に機密性の高い公開プロパティをロックしてください: 上記のように、
#[Locked]
属性を$postId
プロパティで使用しています。上記のようなシナリオで、クライアント側のユーザーにより$postId
プロパティが改竄されないようにする必要がある場合、プロパティを使用する前にプロパティの値を承認するか、#[Locked]
をプロパティに追加して、プロパティが変更されないようにすることが重要です。[!warning] Always lock sensitive public properties As you can see above, we are using the#[Locked]
attribute on the$postId
property. In a scenario like the above, where you want to ensure the$postId
property isn't tampered with by users on the client-side, it's important to authorize the property's value before using it or add#[Locked]
to the property ensure it is never changed.詳細には、ロックするプロパティに関するドキュメントを確認してください。For more information, check out the documentation on Locked properties[/docs/locked].
更新Update
クライアント側のユーザーは、さまざまな方法でpublicプロパティを更新できます。最も一般的なのは、wire:model
を使用して入力を変更することです。Client-side users can update public properties in many different ways, most commonly by modifying an input with wire:model
on it.
Livewireは、公開プロパティの更新をインターセプトするための便利なフックを提供してます。これにより、値を設定する前に値をバリデーションまたは認可したり、プロパティが特定の形式で設定されていることを確認したりできます。Livewire provides convenient hooks to intercept the updating of a public property so that you can validate or authorize a value before it's set, or ensure a property is set in a given format.
以下は、updating
を使用して$postId
プロパティの変更を防ぐ例です。Below is an example of using updating
to prevent the modification of the $postId
property.
この特定の例は、実際のアプリケーションで上記の例のように、#[Locked]
属性を代わりに使用する必要があることに注意してください。It's worth noting that for this particular example, in an actual application, you should use the #[Locked]
attribute[/docs/locked] instead, like in the above example.
use Exception;
use Livewire\Component;
class ShowPost extends Component
{
public $postId = 1;
public function updating($property, $value)
{
// $property: 更新中のカレントプロパティの名前
// $value: プロパティへ設定しようとしている値
if ($property === 'postId') {
throw new Exception;
}
}
// …
}
上記のupdating()
メソッドは、プロパティを更新する前に実行し、無効な入力をキャッチしてプロパティを更新しないようにできます。以下は、updated()
を使用してプロパティの値が一貫性を保つようにする例です。The above updating()
method runs before the property is updated, allowing you to catch invalid input and prevent the property from updating. Below is an example of using updated()
to ensure a property's value stays consistent:
use Livewire\Component;
class CreateUser extends Component
{
public $username = '';
public $email = '';
public function updated($property)
{
// $property: 更新したカレントプロパティの名前
if ($property === 'username') {
$this->username = strtolower($this->username);
}
}
// …
}
これで、$username
プロパティがクライアント側で更新されるたびに、値が常に小文字になるように確実に設定できます。Now, anytime the $username
property is updated client-side, we will ensure that the value will always be lowercase.
更新時フックを使用するときは、多くの場合、特定のプロパティを対象とするため、Livewireでは、メソッド名の一部としてプロパティ名を直接指定できるようにしています。以下は上記と同じ例ですが、この記法を利用して書き直したものです。Because you are often targeting a specific property when using update hooks, Livewire allows you to specify the property name directly as part of the method name. Here's the same example from above but rewritten utilizing this technique:
use Livewire\Component;
class CreateUser extends Component
{
public $username = '';
public $email = '';
public function updatedUsername()
{
$this->username = strtolower($this->username);
}
// …
}
もちろん、この手法はupdating
フックにも適用できます。Of course, you can also apply this technique to the updating
hook.
配列Arrays
配列プロパティには、変更する要素を指定するため、追加の$key
引数をこれらの関数へ渡します。Array properties have an additional $key
argument passed to these functions to specify the changing element.
特定のキーではなく配列自体を更新する場合、$key
引数はnullになることに注意してください。Note that when the array itself is updated instead of a specific key, the $key
argument is null.
use Livewire\Component;
class UpdatePreferences extends Component
{
public $preferences = [];
public function updatedPreferences($value, $key)
{
// $value = 'dark'
// $key = 'theme'
}
// …
}
HydrateとDehydrateHydrate & Dehydrate
HydrateとDehydrateは、あまり知られておらず、あまり利用されないフックです。ただし、特定のシナリオでは強力な効果を発揮します。Hydrate and dehydrate are lesser-known and lesser-utilized hooks. However, there are specific scenarios where they can be powerful.
「dehydrate」および「hydrate」という用語は、Livewire コンポーネントがクライアントサイド用にJSONへシリアル化され、その後のリクエストでPHPオブジェクトへ逆シリアル化されることを指します。The terms "dehydrate" and "hydrate" refer to a Livewire component being serialized to JSON for the client-side and then unserialized back into a PHP object on the subsequent request.
Livewireのコードベースとドキュメント全体で、このプロセスを指すために「hydrate」および「dehydrate」という用語をよく使用します。これらの用語の詳細については、ハイドレトに関するドキュメント を参照してください。We often use the terms "hydrate" and "dehydrate" to refer to this process throughout Livewire's codebase and the documentation. If you'd like more clarity on these terms, you can learn more by consulting our hydration documentation[/docs/hydration].
mount()
、hydrate()
、および dehydrate()
をすべて組み合わせて使用し、Eloquentモデルの代わりにカスタムデータ転送オブジェクト(DTO)を使用して、コンポーネントで投稿データを保存することをサポートする例を見てみましょう。Let's look at an example that uses both mount()
, hydrate()
, and dehydrate()
all together to support using a custom data transfer object (DTO)[https://en.wikipedia.org/wiki/Data_transfer_object] instead of an Eloquent model to store the post data in the component:
use Livewire\Component;
class ShowPost extends Component
{
public $post;
public function mount($title, $content)
{
// 最初の初期リクエストの開始時に実行される
$this->post = new PostDto([
'title' => $title,
'content' => $content,
]);
}
public function hydrate()
{
// すべての「後続」リクエストの開始時に実行される
// これは、最初のリクエストでは実行されない("mount"が実行される)
$this->post = new PostDto($this->post);
}
public function dehydrate()
{
// すべてのリクエストの最後に実行される
$this->post = $this->post->toArray();
}
// …
}
これで、アクションやコンポーネント内の他の場所から、プリミティブデータの代わりに、PostDto
オブジェクトへアクセスできます。Now, from actions and other places inside your component, you can access the PostDto
object instead of the primitive data.
上記の例は、主にhydrate()
およびdehydrate()
フックの機能と性質を示しています。ただし、代わりにWireablesもしくはシンセサイザを使用して、これを行うことをお勧めします。The above example mainly demonstrates the abilities and nature of the hydrate()
and dehydrate()
hooks. However, it is recommended that you use Wireables or Synthesizers[/docs/properties#supporting-custom-types] to accomplish this instead.
レンダーRender
コンポーネントのBladeビューのレンダープロセスへフックしたい場合は、rendering()
およびrendered()
フックを使用できます。If you want to hook into the process of rendering a component's Blade view, you can do so using the rendering()
and rendered()
hooks:
use Livewire\Component;
use App\Models\Post;
class ShowPosts extends Component
{
public function render()
{
return view('livewire.show-posts', [
'post' => Post::all(),
])
}
public function rendering($view, $data)
{
// 指定したビューがレンダーされる前に実行する
//
// $view: レンダリングしようとしているビュー
// $data: ビューへ提供するデータ
}
public function rendered($view, $html)
{
// 提供されたビューがレンダーされた後に実行する
//
// $view: レンダーしたビュー
// $html: 最終的にレンダーしたHTML
}
// …
}
例外Exception
エラーをインターセプトして捕捉することが役立つ場合があります。たとえば、エラーメッセージをカスタマイズしたり、特定の種類の例外を無視したりする場合などです。exception()
フックを使用すると、これを行うことができます。$error
に対してチェックを実行し、$stopPropagation
パラメータを使用して問題を捕捉できます。
これは、validate()
のような内部メソッドで行っている仕組みで、コードのそれ以上の実行を停止したい場合(早期リターン)に強力なパターンを実現します。
use Livewire\Component;
class ShowPost extends Component
{
public function mount() // [tl! highlight:3]
{
$this->post = Post::find($this->postId);
}
public function exception($e, $stopPropagation) {
if ($e instanceof NotFoundException) {
$this->notify('Post is not found');
$stopPropagation();
}
}
// …
}
トレイト内でのフックの使用Using hooks inside a trait
トレイトは、コンポーネント間でコードを再利用したり、単一のコンポーネントから専用のファイルにコードを抽出したりするのに役立つ方法です。Traits are a helpful way to reuse code across components or extract code from a single component into a dedicated file.
ライフサイクルのフックメソッドを宣言するときに、複数のトレイトが互いに競合するのを避けるために、Livewireは、フックメソッドに現在のトレイトのキャメルケース名をプレフィックスとして付けています。To avoid multiple traits conflicting with each other when declaring lifecycle hook methods, Livewire supports prefixing hook methods with the camelCased name of the current trait declaring them.
これにより、複数のトレイトが同じライフサイクルフックを使用でき、競合するメソッド定義を回避できます。This way, you can have multiple traits using the same lifecycle hooks and avoid conflicting method definitions.
以下は、HasPostForm
という名前のトレイトを参照するコンポーネントの例です。Below is an example of a component referencing a trait called HasPostForm
:
use Livewire\Component;
class CreatePost extends Component
{
use HasPostForm;
// …
}
以下は、使用可能なすべてのプレフィックス付きフックを含む実際のHasPostForm
トレイトです。Now here's the actual HasPostForm
trait containing all the available prefixed hooks:
trait HasPostForm
{
public $title = '';
public $content = '';
public function mountHasPostForm()
{
// …
}
public function hydrateHasPostForm()
{
// …
}
public function bootHasPostForm()
{
// …
}
public function updatingHasPostForm()
{
// …
}
public function updatedHasPostForm()
{
// …
}
public function renderingHasPostForm()
{
// …
}
public function renderedHasPostForm()
{
// …
}
public function dehydrateHasPostForm()
{
// …
}
// …
}