🕳️

【Flutter/Dart】onTap: 関数名 と onTap: () => 関数名 の違いでハマった話

に公開

こんにちは!最近Flutterで開発していて、ちょっとしたコードの書き方の違いでハマったのでメモしておきます。きっと誰かの役に立つはず...😅

発端:タップが効かなくなった!

Flutterでアプリを作っていて、InkWellのonTapイベントを実装していたんです。最初はこう書いていました:

onTap: onSelectCategory,

これは正常に動いていました。でも、なぜか「アロー関数の方がスッキリして見えるかな?」と思って、こう書き換えてみたんです:

onTap: () => onSelectCategory,

そしたら突然、タップしても何も反応しなくなってしまいました。何が起きているんだ...🤔

原因:書き方の違いが大きな違いを生む

ググってみた結果、この2つの書き方には重要な違いがあることがわかりました!

1. onTap: onSelectCategory

これは「onSelectCategoryという関数そのものを渡してますよ」という意味です。タップされたとき、Flutterはこの関数を呼び出してくれます。

2. onTap: () => onSelectCategory

これは「タップされたら、() => onSelectCategory というラムダ式(アロー関数)を実行してください」という意味です。でも!このラムダ式は何をするかというと、onSelectCategoryという関数を返すだけで、実行はしないんです!

つまり「関数を実行する」のではなく「関数への参照を返すだけ」になっているので、タップしても何も起きないというわけです。

正しい書き方パターン

パターン1:関数をそのまま渡す(シンプル)

onTap: onSelectCategory,

パターン2:ラムダ式で関数を呼び出す(関数を実行する)

onTap: () => onSelectCategory(),  // 最後の括弧が重要!

パターン3:関数ブロックで書く(複数処理がある場合に便利)

meals/lib/widgets/category_grid_item.dart
onTap: () {
  print('タップされました!');
  onSelectCategory();
},

まとめ: 括弧の有無が命取りに!

Dartの世界では、onSelectCategoryonSelectCategory() は全く別物です。前者は関数そのもの(関数オブジェクト)を参照し、後者は関数を実行した結果になります。

() => onSelectCategory というラムダ式は実行すると onSelectCategory 関数を返すだけで、実際に関数を呼び出さないんですね。正しくは () => onSelectCategory() と書く必要があります。

こんな些細な違いで数時間も悩んでしまいました...(笑) みなさんも気をつけてください!

Discussion