こんにちは、コバヤシです。
今回は前回書いた記事「Laravel8でLivewireを試してみる:実践編」に続いてLivewireのライフサイクルについて書いていきます。
ライフサイクルとは
簡単に言えば、ライブラリが読み込まれて、すべての処理が完了するまでの一連の流れがライフサイクルとなります。
このライフサイクルの中の各ポイントで、フックすることで、実行したいタイミングで処理を行うことが可能です。
Livewireにもライフサイクルにフック出来る箇所が設けられているので利用して制作していきます。
Livewireのライフサイクルフック
公式によれば以下が設定されています。
フック | 説明 |
---|---|
boot | コンポーネントがインスタンス化された直後、他のライフサイクル・メソッド が呼び出される前に、すべてのリクエストに対して実行します |
mount | コンポーネントがインスタンス化された直後、ただしrender()が呼び出される 前に1回実行します |
hydrate | コンポーネントがハイドレイトされた後、アクションが実行される、 またはrender()が呼び出される前に、後続のすべてのリクエストで実行します |
hydrateFoo | 名前が$fooのプロパティがハイドレイトされた後に実行します |
dehydrate | コンポーネントがデハイドレイトされる前、render()が呼び出された後に、 後続のすべてのリクエストで実行します |
dehydrateFoo | 名前が$fooのプロパティがデハイドレイトされる前に実行します |
updating | Livewireコンポーネントのデータが更新される前に実行します (PHP内ではなく、wire:modelを使用) |
updated | Livewireコンポーネントのデータが更新された後に実行します (PHP内ではなく、wire:modelを使用) |
updatingFoo | 名前が$fooのプロパティが更新される前に実行します。配列プロパティでは、 追加の$key引数があり、updatingArray($value, $key)の形式でこの関数へ渡し、 配列内の変更する要素を指定できます |
updatedFoo | 名前が$fooのプロパティが更新された後に実行されます。前記のように、 配列プロパティでは、追加の$key引数があります |
updatingFooBar | $fooプロパティのネストしたプロパティbarや、$fooBarか$foo_barなどの マルチワードプロパティを更新する前に実行します |
updatedFooBar | $fooプロパティのネストしたプロパティbarや、$fooBarか$foo_barなどの マルチワードプロパティを更新した後に実行します |
ライフサイクルの順番
実際のライフサイクルの順番は、どうなっているのか見ていきたいと思います。
以下のような処理を書いて実行してみます。
ボタンをクリックするとカウントアップ、テキスト入力でコンポーネント内の変数とwire-modelで同期します。
<div> <h2>{{ $count }}</h2> <p><button wire:click="countup">カウントアップ</button></p> <h2>{{ $input }}</h2> <p><input type="text" name="input" wire:model="input"></p> </div>
<?php class IndexController extends \App\Http\Controllers\Controller { public function index() { \Log::debug('start'); return view('index'); } }
<?php class Lifecycle extends Component { public $count = 0; public $input; public function boot() { \Log::debug('boot'); } public function mount() { \Log::debug('mount'); } public function hydrate() { \Log::debug('hydrate'); } public function hydrateCount() { \Log::debug('hydrate count'); } public function hydrateInput() { \Log::debug('hydrate input'); } public function dehydrate() { \Log::debug('dehydrate'); } public function dehydrateCount() { \Log::debug('dehydrate count'); } public function dehydrateInput() { \Log::debug('dehydrate input'); } public function updating() { \Log::debug('updating'); } public function updated() { \Log::debug('updated'); } public function updatingCount() { \Log::debug('updating count'); } public function updatingInput() { \Log::debug('updating input'); } public function updatedCount() { \Log::debug('updated count'); } public function updatedInput() { \Log::debug('updated input'); } public function render() { \Log::debug('render'); return view('livewire.lifecycle'); } public function countup() { $this->count++; \Log::debug('countup'); } }
初期表示
まずは、表示しただけ。
local.DEBUG: start local.DEBUG: boot local.DEBUG: mount local.DEBUG: render local.DEBUG: dehydrate local.DEBUG: dehydrate count local.DEBUG: dehydrate input
Controllerでのviewの表示(start)、次にLivewireの表示となりboot、mountと続きrenderとなります。
概ね公式の通りですが、hydrateが無いのにdehydrateがあるのが解せないところです。
カウントアップ(メソッドによる変数更新)
次にカウントアップをしてみます。
local.DEBUG: boot local.DEBUG: hydrate count local.DEBUG: hydrate input local.DEBUG: hydrate local.DEBUG: increment local.DEBUG: render local.DEBUG: dehydrate local.DEBUG: dehydrate count local.DEBUG: dehydrate input
初回表示ではないので、mountは実行されていませんね。
又、今回はhydrateが行われています。
hydrateは、変数→コンポーネントの順番で実行され、dehydrateはコンポーネント→変数の順番で実行されることがわかります。
試しに、以下のように順番を変えてみたところ
<?php public $input; public $count = 0;
以下のようになりました。
local.DEBUG: boot local.DEBUG: hydrate input local.DEBUG: hydrate count local.DEBUG: hydrate local.DEBUG: countup local.DEBUG: render local.DEBUG: dehydrate local.DEBUG: dehydrate input local.DEBUG: dehydrate count
変数の宣言順に、処理が行われることが判明しました。
テキスト入力(wire-modelの同期による変数更新)
最後にテキストに入力して、wire-modelの同期を行います。
local.DEBUG: boot local.DEBUG: hydrate count local.DEBUG: hydrate input local.DEBUG: hydrate local.DEBUG: updating local.DEBUG: updating input local.DEBUG: updated local.DEBUG: updated input local.DEBUG: render local.DEBUG: dehydrate local.DEBUG: dehydrate count local.DEBUG: dehydrate input
カウントアップ時には無かった、updating・updatedがあります。
公式に書かれているように、wire-modelの同期の時のみ実行されているのがわかりました。
コンポーネント→変数の順番で処理されていますね。
まとめ
ライフサイクルについて簡単にまとめてみました。
共通処理はboot、初期化処理はmountで行えば良さそうです。
初期表示時にhydrateが実行されないこと、変数の更新方法で実行されるフックが違うことには注意が必要ですが、 適切に処理できれば問題ないと思います。
ライフサクルのフックを活用していきましょう!
次回更新は2022年5月11日(水)を予定しています。