Laravel Livewire 親子コンポーネント間での値の受け渡し

## 内容
LaravelのLivewireを使用している環境での、親子間での値の受け渡し方法を書いています。
基本的には値を渡したいコンポーネントの関数を呼び出して値を伝達するのが良いと思います。

## 注意： Livewireのバージョンに注意しましょう
バージョンの違うドキュメントを見て時間を溶かしました。
バージョン 2.x なのか、3.xなのか初めに確認してください。
私はバージョン 3.xです。

## 親から子へ値を渡す
### wire:propディレクティブによる値渡し
子コンポーネントを描画する際に、`:タグ名="値"`と記述することで、値を渡すことができます。
この方法の場合、リアルタイムな値の反映はできません。


```HTML:livewire Blade
<livewire:child-component :number="$num" />
```


タグと値を受け取ったコンポーネントは、以下の条件に一致するコンポーネントクラスのプロパティへ代入を行います。
- タグ名とプロパティ名が一致する
- publicなプロパティ

```PHP:PHP コンポーネントクラス
class ChildComponent extends Component
{
    public $number;
    ...
}
```

### 親から子のイベントを発火させての値渡し
親コンポーネントにて、子コンポーネントへの値伝達を開始するトリガーを実装します。
この方法の場合、リアルタイムな値の反映が可能です。

以下の二つがあるかと思います。
1. `wire:click`を使って、クリックなどのアクションをトリガーにする
1. 親コンポーネントクラスのプロパティが変更されたことを検知する`updatedプロパティ名`のメソッドを実装。`wire:model.live`にて、値の変更を毎回検知してトリガーにする

私は2の方法で実装しました。

まず、親bladeに、wire:model.liveを記述し、値変更をすぐに検知するようにします。
```HTML:親 livewire Blade
<input type="text" wire:model.live="parentText">
```

親コンポーネントクラスで、以下を記述します。
1. bladeと同名のプロパティ
1. updatedプロパティ名のメソッド

```PHP:親 PHP コンポーネントクラス
class ParentComponent extends Component
{
    // bladeと同名のプロパティを記述
    public $parentText = "";

    // updatedプロパティ名のルールに従ってメソッドを記述
    // $parentTextの値が変更されるたびに呼ばれる
    public function updatedParentText()
    {
        // dispatch
        // 第一引数に記述されたイベントが発行されます
        // イベントをリッスンしている子コンポーネントが発火します
        // 第二引数の値が、発火した関数に渡されます
        $this->dispatch('updateText', $this->parentText);
    }

    public function render()
    {
        return view('livewire.parent-component');
    }
}
```

子コンポーネントクラスで、以下を記述します。
1. リッスンするイベント`protected $listeners`
1. イベント発行を検知して起動するメソッド

```PHP:子 PHP コンポーネントクラス
class ChildComponent extends Component
{
    public $childText;

    // リッスンするイベント名
    protected $listeners = ['updateText'];

    // イベント検知時に起動するメソッド
    public function updateText($text)
    {
        // 親コンポーネントクラスから受け取った値を
        // 自身のプロパティへ代入
        $this->childText = $text;
    }

    public function render()
    {
        return view('livewire.child-component');
    }
}
```

子bladeに、wire:model.liveを記述し、値変更をすぐに反映するようにします。

```HTML:子 livewire Blade
<input type="text" wire:model.live="childText">
```

## 子から親へ値を渡す
基本的には上記の内容（[親から子のイベントを発火させての値渡し](https://qiita.com/drafts/493f8cfe95500c2cf2a3/edit#%E8%A6%AA%E3%81%8B%E3%82%89%E5%AD%90%E3%81%AE%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E3%82%92%E7%99%BA%E7%81%AB%E3%81%95%E3%81%9B%E3%81%A6%E3%81%AE%E5%80%A4%E6%B8%A1%E3%81%97)）の逆をやります。
バージョン 2.xだとそれぞれやり方が違うようですが、バージョン 3.xだと基本的に同じやり方でできるようです。
参考用にコードだけ記述します。

```HTML:親 livewire Blade
<input type="text" wire:model.live="parentText">
```

```PHP:親 PHP コンポーネントクラス
class ParentComponent extends Component
{
    public $parentText = "";

    protected $listeners = ['updateText'];

    public function updateText($text)
    {
        $this->parentText = $text;
    }
    
    public function render()
    {
        return view('livewire.parent-component');
    }
}
```

```PHP:子 PHP コンポーネントクラス
class ChildComponent extends Component
{
    public $childText;

    public function updatedChildText()
    {
        $this->dispatch('updateText', $this->childText);
    }

    public function render()
    {
        return view('livewire.child-component');
    }
}
```

```HTML:子 livewire Blade
<input type="text" wire:model.live="childText">
```


## Livewireコンポーネント描画時の注意点
以下のような、子コンポーネントを複数回描画する記述を行った場合、何かの再描画のタイミングでコンポーネントが消えてしまうことがあります。
```HTML
@for ($i = 0; $i < 5; $i++)
    <livewire:child-component />
@endfor
```

その場合、以下のように`wire:key`を記述して、そのページにてユニークなkeyを設定してあげると解消することがあります。
これはLivewireが識別のために使用するだけなので、この記述を追加したからと言ってコンポーネントクラスに何か書いたりする必要はありません。
```HTML
@for ($i = 0; $i < 5; $i++)
    <livewire:child-component :wire:key="$i" />
@endfor
```

## 参考URL
[公式ドキュメント](https://livewire.laravel.com/)

非常に参考になりますが、バージョン 2.xである点に注意してください。
[Laravel で爆速ラクチン🔥に動的な機能を開発や！Livewire2.x 解説🔥](https://qiita.com/sgrs38/items/ee36ecc18fd0b7b3ba38)