Stimulusの簡単なサンプルコードを読めるようになる記事

# はじめに

最近stimulusを触る機会があったのでその基本をまとめようと思います。
この記事は [Stimulus公式リファレンス](https://stimulus.hotwired.dev/) を基に作成しています。

# Stimulusの基本

### Stimulusってどんなコード？

Stimulusはコントローラー・アクション・ターゲットという3つの要素で成り立っています。
基本的には、あるアクションが発生した際に、コントローラーに定義した関数を用いて、ターゲット要素に対して何かしら干渉するというフローです。
<br>
突然ですが問題です。以下のコードはどのような動作をするでしょうか？
（以下のコードはStimulusを用いて書かれていますが、一度目を通してみてください）
```sample.html
<div data-controller="clipboard">
  PIN: <input data-clipboard-target="source" type="text" value="1234" readonly>
  <button data-action="click->clipboard#copy">Copy to Clipboard</button>
</div>
```

「Copy to Clipboardというボタンをクリックすると、copyという関数が走って、sourceというターゲットの要素をコピーできるんだろうな〜」と予想できると思います。

このように、Stimulusのコードについて何も知らなくても、それを読んで何が起こるのかを理解しやすいので学習コストが低くとっかかりやすいと思います。

## 基本的な構造

では、Stimulusの基本的な構造に関して、上記とは別のサンプルコードを用いて説明していきます。
このコードは、名前を入力して「Greet」ボタンを押すと、”Hello, 〇〇!”という形式で文字を出力するものです。

```sample.html
<div data-controller="hello">
  <input data-hello-target="name" type="text">

  <button data-action="click->hello#greet">
    Greet
  </button>

  <span data-hello-target="output">
  </span>
</div>
```

```hello_controller.js
import { Controller } from "stimulus"

export default class extends Controller {
  static targets = [ "name", "output" ]

  greet() {
    this.outputTarget.textContent =
      `Hello, ${this.nameTarget.value}!`
  }
}
```

↓UIは以下のようになっているとイメージしていただくとわかりやすいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3551848/f36c1441-a8b9-4064-b575-bab3d90a6479.png)

では、このコードをコントローラー・アクション・ターゲットという3つの観点から説明していきます。

### controller
controllerはターゲット要素や関数を定義する場所です。
```hello_controller.js
static targets = [ "name", "output" ]
```

ここでは`static targets = [ "name", "output" ]`でターゲット要素を定義していますね。

これによってコントローラー内で`name`と`output`に対して何かしら干渉することができます。

```hello_controller.js
greet() {
    this.outputTarget.textContent =
      `Hello, ${this.nameTarget.value}!`
  }
```
ここでは`greet`という関数（アクション）を定義していますね。

`this.outputTarget`のように`this.【ターゲット名】Target`の形式でターゲット要素に干渉することができます。
関数の内容は、`output`というターゲットのテキスト要素を`name`というターゲットの値を使って書き換えているとわかりますね。

```sample.html
<div data-controller="hello">
	・・・
</div>
```

ここでは`data-controller=”hello”`でdata属性を付与していますね。

このように`data-controller=”【コントローラー名】”`とHTML側にdata属性を付与することで指定の範囲内においてcontrollerに定義した内容を用いることができます。

指定の範囲内というのは、サンプルコードでいうところの`<div data-controller="hello">`以下の階層の要素が該当します。

※これより上の階層の要素に対してcontrollerで定義した内容は基本的には使用できないので注意してください。（今回は説明を省略しますが、ある方法を用いることで使用することができます。）
<br>
**命名規則**
- 関数名とターゲットは常にキャメルケースで書く
- ファイル名はスネークまたはケバブケースで書く
- onClickなど、アクション名をみてどのような処理が行われるのかわからない命名はしない

### target

```sample.html
<input data-hello-target="name" type="text">
```

```sample.html
<span data-hello-target="output">
```

ここでは`data-hello-target="name"`と`data-hello-target="output"`でdata属性を付与し、要素をターゲットとして指定していますね。

このように`data-【コントローラー名】-target=”【ターゲット名】”`とHTML側にdata属性を付与することでcontrollerからターゲットを参照することができます。

ターゲットに指定したものに対して、controllerで値を参照したり、値を書き換えたりとJSでできることは大抵できます。
<br>
**ターゲット名の命名規則**
- 常にキャメルケースで書く

### action

```sample.html
<button data-action="click->hello#greet">
   Greet
</button>
```
ここでは`data-action="click->hello#greet"`でdata属性を付与していますね。

このように`data-action="【イベント】->【コントローラー名】#【アクション名（コントローラーに定義した関数）】"` とHTML側にdata属性を付与することで、指定のイベントが発生した際に、どのコントローラーのどの関数が発火するのかを決めることができます。

**アクション名の命名規則**

- 常にキャメルケースで書く
- onClickなど、アクション名をみてどのような処理が行われるのかわからない命名はしない

# おわりに
これでStimulusの基本は理解できたと思います。
この記事がStimulus学習のきっかけになれば幸いです。
最後まで読んでいただきありがとうございました。