MultiProviderの定義場所

main.dart が provider だらけ問題の解決パターン

「main.dart が provider だらけでゴチャゴチャ問題」代表的な解決パターン

1. Provider の定義を別ファイルに切り出す

もっともシンプルなやり方です。

・before(よくある main.dart)

main.dart

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => AuthViewModel()),
        ChangeNotifierProvider(create: (_) => UserViewModel()),
        ChangeNotifierProvider(create: (_) => SettingsViewModel()),
        ChangeNotifierProvider(create: (_) => ProductViewModel()),
        // ...どんどん増える...
      ],
      child: const MyApp(),
    ),
  );
}
    

・after(providers.dart にまとめる)

providers.dart

// providers.dart
import 'package:provider/provider.dart';

import 'viewmodels/auth_view_model.dart';
import 'viewmodels/user_view_model.dart';
import 'viewmodels/settings_view_model.dart';
import 'viewmodels/product_view_model.dart';

final globalProviders = [
  ChangeNotifierProvider(create: (_) => AuthViewModel()),
  ChangeNotifierProvider(create: (_) => UserViewModel()),
  ChangeNotifierProvider(create: (_) => SettingsViewModel()),
  ChangeNotifierProvider(create: (_) => ProductViewModel()),
];
    
main.dart

// main.dart
import 'providers.dart';

void main() {
  runApp(
    MultiProvider(
      providers: globalProviders,
      child: const MyApp(),
    ),
  );
}
    

2. AppProviders というラッパー Widget を作る

Widget として包むパターンも整理しやすく有効です。

app_providers.dart

// app_providers.dart
class AppProviders extends StatelessWidget {
  final Widget child;

  const AppProviders({super.key, required this.child});

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => AuthViewModel()),
        ChangeNotifierProvider(create: (_) => UserViewModel()),
      ],
      child: child,
    );
  }
}
    
main.dart

// main.dart
void main() {
  runApp(
    AppProviders(
      child: const MyApp(),
    ),
  );
}
    

3. 必要なものだけ root に置く(機能ごとに分散)

役割ごとに Provider を分散させることで、main.dart の肥大化を防げます。

user_page.dart

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

  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => UserViewModel()),
        ChangeNotifierProvider(create: (_) => UserDetailViewModel()),
      ],
      child: const UserPageBody(),
    );
  }
}
    

4. DI コンテナ(get_it 等)と組み合わせる

大規模プロジェクトでは DI コンテナを併用することで責務分離が進みます。

example.dart

ChangeNotifierProvider(
  create: (_) => getIt(),
);
    

まとめ

  • ・providers.dart や AppProviders で定義を分離
  • ・本当に必要なものだけ root に置く
  • ・画面単位の Provider は画面側に配置

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です