【Flutter/Dart】onTap: 関数名 と onTap: () => 関数名 の違いでハマった話
こんにちは!最近Flutterで開発していて、ちょっとしたコードの書き方の違いでハマったのでメモしておきます。きっと誰かの役に立つはず...😅
発端:タップが効かなくなった!
Flutterでアプリを作っていて、InkWell
のonTapイベントを実装していたんです。最初はこう書いていました:
onTap: onSelectCategory,
これは正常に動いていました。でも、なぜか「アロー関数の方がスッキリして見えるかな?」と思って、こう書き換えてみたんです:
onTap: () => onSelectCategory,
そしたら突然、タップしても何も反応しなくなってしまいました。何が起きているんだ...🤔
原因:書き方の違いが大きな違いを生む
ググってみた結果、この2つの書き方には重要な違いがあることがわかりました!
onTap: onSelectCategory
1. これは「onSelectCategoryという関数そのものを渡してますよ」という意味です。タップされたとき、Flutterはこの関数を呼び出してくれます。
onTap: () => onSelectCategory
2. これは「タップされたら、() => onSelectCategory というラムダ式(アロー関数)を実行してください」という意味です。でも!このラムダ式は何をするかというと、onSelectCategoryという関数を返すだけで、実行はしないんです!
つまり「関数を実行する」のではなく「関数への参照を返すだけ」になっているので、タップしても何も起きないというわけです。
正しい書き方パターン
パターン1:関数をそのまま渡す(シンプル)
onTap: onSelectCategory,
パターン2:ラムダ式で関数を呼び出す(関数を実行する)
onTap: () => onSelectCategory(), // 最後の括弧が重要!
パターン3:関数ブロックで書く(複数処理がある場合に便利)
onTap: () {
print('タップされました!');
onSelectCategory();
},
まとめ: 括弧の有無が命取りに!
Dartの世界では、onSelectCategory
と onSelectCategory()
は全く別物です。前者は関数そのもの(関数オブジェクト)を参照し、後者は関数を実行した結果になります。
() => onSelectCategory
というラムダ式は実行すると onSelectCategory
関数を返すだけで、実際に関数を呼び出さないんですね。正しくは () => onSelectCategory()
と書く必要があります。
こんな些細な違いで数時間も悩んでしまいました...(笑) みなさんも気をつけてください!
Discussion