【Laravel Livewire】ライフサイクルフックのhydrate、dehydrateとは何か


# 事の発端

https://readouble.com/livewire/2.x/ja/lifecycle-hooks.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/95f1be8a-e506-09a0-5d0f-cc72ae9fefc5.png)

**hydrate**と**dehydrate**って何だよ。

解説しているブログとか記事が無い。調べてみるか

## 前提
>livewireは、コンポーネント内のイベントが発火する度に、バックエンドで生成したHTMLをView側で受け取り差し替えています。
バックエンド側ではHTMLを渡すと同時にコンポーネント内のプロパティをオブジェクトに変換して渡しています。

# 先に結論
要約すると多分こうです。

| フック       | 説明                                                                | 
| ------------ | ------------------------------------------------------------------- | 
| hydrateFoo   | View側から送られてきた<strong>{ foo }</strong>オブジェクトを<strong>$foo</strong>に変換した後に実行される | 
| dehydrateFoo | PHP側でHTMLを生成した後に<strong>$foo</strong>を<strong>{ foo }</strong>オブジェクトに変換する時に実行される  | 

## stackoverflowでの回答


https://stackoverflow.com/questions/65500135/what-does-it-mean-to-hydrate-and-dehydrate-a-laravel-livewire-component


# サンプルコードとライフサイクル

https://laravel-livewire.com/docs/2.x/security#introduction

```php
class Counter extends Component
{
    public $count = 1;
 
    public function increment()
    {
        $this->count++;
    }
 
    public function render()
    {
        return view('livewire.counter');
    }
}
```
```html
<div>
    <h1>{{ $count }}</h1>
 
    <button wire:click="increment">+</button>
</div>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/8f894240-23a5-cad1-7785-838a023be9a3.png)

どういう事？

# サンプルのコードの動きを見てみる

chromeのlivewireデバッグ拡張機能で見てみます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/3e6f2d62-92e2-26c8-294f-dc1bd157331e.png)


+ボタンを押す


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/431ab6f5-7695-dc02-4527-f447880dd91a.png)

<details>
<summary><strong>クリックで右側拡大表示</strong></summary>
<div>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/3ea79a75-4ddf-fbaf-acdd-68978accae72.png)

</div>
</details>

はい、生成したhtmlとオブジェクト``{count : 2}``を受け取っていますね

# hydrateCountメソッドを追加してみよう

|  フック  |  説明  |
| ---- | ---- |
|  hydrateFoo  |  名前が$fooのプロパティがハイドレイトされた後に実行します  |

ライフサイクルフックにあるからどこかのタイミングで動くんだろう。試してみるか

サンプルのコードに処理を加えます

```diff_php
class Counter extends Component
{
    public $count = 1;

    public function increment()
    {
        $this->count++;
    }

+   public function hydrateCount()
+   {
+       $this->count++;
+   }

    public function render()
    {
        return view('livewire.counter');
    }
}

```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/f2ff43dc-0920-7134-21c0-dd34c934704e.png)

クリックします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/c8fcdbd3-aa80-df5d-28aa-7cda455d1b76.png)

<details>
<summary><strong>クリックで右側拡大表示</strong></summary>
<div>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/63ed53e1-cdd3-cf37-ea46-cf894133e73a.png)


</div>
</details>

生成されたHTMLの``$count``と``count``オブジェクト両方3ですね。

``{count:1}``をhydrateする時に実行されていると、ふむ・・・、よく分からんのでdehydrateの処理を書きます

# dehydrateCountメソッドを追加してみよう

|  フック  |  説明  |
| ---- | ---- |
|  dehydrateFoo  |  名前が$fooのプロパティがデハイドレイトされる前に実行します  |

```diff_php
class Counter extends Component
{
    public $count = 1;

    public function increment()
    {
        $this->count++;
    }

+   public function dehydrateCount()
+   {
+       $this->count++;
+   }

    public function render()
    {
        return view('livewire.counter');
    }
}

```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/af7e8a4c-ccd6-ddd3-fc14-9125a7670b4a.png)


ん？2？？？？？？
HTML内の``$count``は1だけどオブジェクトの``count``は2??

クリックして見るか

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/d663bd7a-3bc7-f0d0-b60b-520fd44c3a36.png)

<details>
<summary><strong>クリックで右側拡大表示</strong></summary>
<div>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282328/cb12674f-bf61-a790-3515-3b5be85dbd7b.png)


</div>
</details>

なるほど、HTML内の``$count``は3でオブジェクトの``count``は4と

hydrateはオブジェクトをphpの変数に変換的な事をする時に走って、dehydrateはphpの変数をオブジェクトにして返す時に走ってるんや！！

## dehydrateCountメソッドがある場合の流れ

図にするとこう、ページを開いた時の流れ。
```mermaid
sequenceDiagram
 participant View as View
 participant PHP as PHP
Note over PHP: $count = 1
PHP->>PHP:HTML生成
PHP->>+ PHP:dehydrateCount()
Note over PHP: $count = 2
Note over PHP: $count = 2 → { count: 2 }
PHP->>View:生成したHTMLで描画
Note over View:{ count: 2 }
```

:::note warn
``$count``が1の時にHTMLを生成しているのでHTML内では1が表示される。
HTML生成後に加算されているのでオブジェクト``count``は2
:::

初回以降の流れ
```mermaid
sequenceDiagram
 participant View as View
 participant PHP as PHP
Note over View: { count: 2 }
View->>PHP:wire:click="increment"
Note over PHP: { count: 2 } → $count = 2
PHP->>PHP:increment()
Note over PHP: $count = 3
PHP->>PHP:HTML生成
PHP->>+ PHP:dehydrateCount()
Note over PHP: $count = 4
Note over PHP: $count = 4 → { count: 4 }
PHP->>View:HTMLとオブジェクトを渡す
Note over View: { count: 4 }

```