🙌

main.dartにどこまで書くべきか

に公開

はじめに

私はiOSエンジニアとして1年弱開発をし、1週間前にFlutterエンジニアに転向しました。今回はFlutterを1週間やってみて1番疑問を抱いた「main.dartにどこまで書くの?」と言う疑問を記事にしてみました。

まずmain.dartとは

main.dartはアプリのエントリーポイント(スタート地点)のことで必ずこのmain.dartを通ります。高校野球をやるのに坊主頭にするのが避けられないと同じでmain.dartを通らずに処理を行うことはできません。野球をやるのに髪を剃るのを強制させる意味はありませんが、main.dartではアプリ全体に大きな意味を持ちます。

main.dartのデフォルトメソッド

Flutterプロジェクトを新規作成すると、最初に生成されるmain.dartは以下のようになっています。

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      home: const HomePage(),
    );
  }
}

main() 関数:アプリの起動地点。ここで runApp() を呼ぶのがルール。

MyApp クラス:MaterialApp(アプリ全体の設定やルーティング)を返すウィジェット。

home: に指定した MyHomePage が最初の画面になります。

main.dartに処理を書きすぎた例

例えばユーザーのログイン状態で最初の画面を分けると言うアプリがあったとしましょう。

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  final isLoggedIn = await AuthService().checkLoginStatus();
  final isFirstTime = await UserService().isFirstLaunch();

  runApp(
    MaterialApp(
      title: 'My App',
      home: isLoggedIn
          ? const HomePage()
          : isFirstTime
              ? const SignupPage()
              : const LoginPage(),
    ),
  );
}

このコードだとmain.dartに責務が集中し、保守やテストがしにくくなります。

理想の形

前回の例ではログイン状態や初回起動時の判定ロジックをmai.dartに書いてしまっていました。これを止めるには分岐の処理を別のwidgetに任せることです。

void main() {
  runApp(
    MaterialApp(
      title: 'My App',
      home: const UserJudge(), // ← 分岐処理はこの中で
    ),
  );
}

そしてUserJudgeクラスには以下のように書きます。

class UserJudge extends StatelessWidget {
  const UserJudge({super.key});

  Future<Widget> _getInitialScreen() async {
    final isLoggedIn = await AuthService().checkLoginStatus();
    final isFirstTime = await UserService().isFirstLaunch();

    if (isLoggedIn) {
      return const HomePage();
    } else if (isFirstTime) {
      return const SignupPage();
    } else {
      return const LoginPage();
    }
  }

  //続きの画面遷移処理
SignupPage()signinPage()などの画面遷移処理が続く

最後に

「main.dartにどこまで書くの?」という問いに対して、私なりの答えはこんな感じです。

"main.dartには、アプリの起動と初期化処理だけを書いて、それ以外の処理は別のWidgetやファイルに任せるのがベスト。"

UIの構築、画面遷移、状態管理などを全部main.dartに書いてしまうと、ファイルが肥大化して保守しにくくなります。

今回は「ログイン状態によって初期画面を分岐する」というシンプルな例で処理を切り出す方法を紹介しました。今後Flutterでアプリを開発する中でも、

この処理はmain.dartに書いていいのか?
それとも別のWidgetに分けるべきか?

という視点を常に持ちながら、責任を分けたコード設計を意識していこうと思います。

採用情報

株式会社ジャンボではエンジニアを 募集中 です!
カジュアル面談もウェルカムなのでお気軽にどうぞ

Jambo Tech Blog

Discussion