イベントハンドラにどんな名前をつけるか

Twitterとかでちょっと盛り上がってたので自分の意見を書いておきます。 (参考情報ですが)筆者はVueを書くことが多くて、React方面の事情はあんまり詳しくないです。

「handleClick」を避けたい理由

率直な気持ちを言うと、この命名を考えなしに使うのは避けたほうがいいと思います。 理由はこの命名をした関数はクリックイベントのハンドラにしか使えない(ように見える)からです。 そして、ひとたびこの命名を許せば、特に命名に気を使わない他のエンジニアがhandleなんとかを乱用してコードの治安が失われていく懸念が高まるからです。

近年のVueはComposition APIを使ってロジックをコンポーネントから切り離すことが一般的になりました。 筆者がデータとそれに関連する操作のコードを書くときは、以下のようなパターンのcomposableをよく使います。

/**
 * 例) メールアドレスの入力フォームのロジック
 */
export const useEmailInput = () => {
  // なんかしらのデータ
  const email = ref('')
    
  // 二重サブミットの防止
  const pending = ref(false)
    
  // データに関する操作
  const saveEmail = async () => {
    pending.value = true
    try {
      // ここでなんかしらの処理
    } finally {
      pending.value = false
    }
  }
  
  return { email, pending, saveEmail }
}

上のコード例でsaveEmailにたとえばhandleClickという名前をつけてしまうと、せっかくコンポーネントから自由になったロジックに不必要に利用方法の制約を課してしまうことになります。 Vueの合成可能関数は他の関数内で呼び出されるケースなども考えられますので、安易にUI上の操作に束縛される名前をつけるとコードが汚くなる要因となります。

元の投稿で指摘されている情報量がゼロ(処理の中身が何なのかわからない)というのは筆者にとっては副次的な理由で、 メインの理由は「コンポーネント(UI)とロジックの間の結合度を低く保ち、ロジックの再利用性・ポータビリティを高く維持したい」になります。

さらに、saveEmailのように具体的な処理を関数名に用いることで、将来このコードを改修する人がここに余計な処理を書き加える可能性を抑えることができそうな気もします(少なくとも、何をするかわからない名前をつけるよりは)。 handleClickという命名をした関数はクリックイベントを処理してさえいれば将来的にどのような処理をするように改修しても差し支えない、と表明していると勘違いされても仕方ありません。

「handleClick」を使うとき

上に書いたような避けたい理由を無視してよい状況においては、handleClickのような具体的なイベントを含む命名を使っても問題はないと思います。

たとえば:

  • 関数の引数としてclickイベントを受け取る必要がある場合
  • clickイベントを受け取るUIコンポーネントとロジックが密結合している場合
  • clickイベントを処理してさえいれば、中身の処理がどうなってもよいということを表明したい場合

などが考えられます。

<script setup lang="ts">
// Eventが必要なら無理に避ける必要はない
const handleClick = (event: Event) => {
  // ......
} 
</script>

まとめ

どんな関数でも「その関数をどのように利用してほしいか」「その関数が何をするか」の2つの要素がいい感じに伝わるように命名されていてほしいです。 命名をした人が大切だと考えたことが関数のシグネチャに必要十分に表現されていることが最も重要と思います。

なので、たとえば「clickイベントのハンドラとして使ってほしい」という願いのもとに生まれた関数にはhandleClickという名前が与えられて然るべきでしょう。

share with:
この記事をTwitterで共有
この記事をはてなブックマークに追加