Flutter初学者です。
アプリの起動時に、以下のように画面を切り替えようとしています。
①ログインしていれば「メニュー画面」
②でなければ「ログイン画面」
①でメニュー画面を描写する際、複数の非同期処理(APIからデータ取得処理)を行い、取得したデータを「状態(以下、ストア)」に保存したいと考えています。
しかしながら、FutureBuilderでこれを行おうとすると、「API取得用関数」と「スピナー表示」の箇所でループが発生してしまいます。
下記の【試したこと】にもありますが、無限ループが発生する場合としない場合があり、
①なぜ発生するのか
②FutureBulderで複数処理を行う場合はどのようにしたらよろしいのか
の2点をお教えいただければと思います。
宜しくお願い致します。
※初学者故、汚いコードとなっていますが、ご容赦願います。
【コード】
main.dart
dart
1void main(){ 2 runApp( 3 MultiProvider( 4 providers: [ 5 ChangeNotifierProvider( 6 create: (context) => UserStore(), 7 ), 8 ChangeNotifierProvider( 9 create: (context) => AccurateAttendanceStore(), 10 ), 11 ], 12 child: MyApp(), 13 ) 14 ); 15 // runApp(MyApp()); 16} 17 18class MyApp extends StatelessWidget { 19...略.... 20 home: _LoginCheck(), 21...略... 22} 23 24class _LoginCheck extends StatelessWidget { 25 26 Widget build(BuildContext context) { 27 28 // 現在の日付を取得 29 DateTime now = DateTime.now(); 30 final DateFormat formatter = DateFormat('yyyy-MM-dd'); 31 String formatted = formatter.format(now); 32 33 // APIの複数取得処理 34 Future <List<bool>> multi () async{ 35 try{ 36 List<bool> result = []; 37 final userStore = Provider.of<UserStore>(context); 38 final accurateAttendanceStore = Provider.of<AccurateAttendanceStore>(context); 39 40 // トークンでのログイン 41 User user = await APIAccessor().tokenLogin(); 42 await userStore.setUserBasicInfoWithToken(user); 43 userStore.user != null ? result.add(true) : result.add(false); 44 45 // 勤務情報取得 46 Attendance resAttendance = await APIAccessor().getAttendance(userStore.user.id, formatted); 47 await accurateAttendanceStore.setAccurateAttendance(resAttendance); 48 accurateAttendanceStore.attendance != null ? result.add(true) : result.add(false); 49 50 return result; 51 } 52 catch (e) { 53 return e; 54 } 55 } 56 57 return FutureBuilder( 58 future: multi(), 59 builder: (BuildContext context, AsyncSnapshot<List<bool>> snapshot) { 60 // 通信中はスピナーを表示 61 if (snapshot.connectionState != ConnectionState.done) { 62 return Scaffold( 63 body: Center( 64 child: Column( 65 mainAxisSize: MainAxisSize.min, 66 children: <Widget>[ 67 CircularProgressIndicator(), 68 ], 69 ), 70 ), 71 ); 72 } 73 if(snapshot.hasData){ 74 // ユーザーデータと他のデータが取得できたらメニューへ 75 if(snapshot.data[0] && snapshot.data[1]) { 76 return Menu(); 77 } 78 else { 79 return Login(); 80 } 81 } 82 else { 83 return Login(); 84 } 85 } 86 ); 87 } 88}
【試したこと】
①FutureBuilderをネストした場合、正常処理になりました。
※FutureBuilderのネストとは、以下のような構造です。
dart
1return FutureBuilder( 2 future: 処理1, 3 builder: (BuildContext context, AsyncSnapshot snapshot) { 4 if(snapshot.hasData){ 5 return FutureBuilder( 6 future: 処理2, 7 ); 8 } 9 else { 10 return ...; 11 } 12 } 13 else { 14 return ...; 15 } 16 } 17 );
②Future.wait()関数をFutureBuilderのfutureに設定してみましたが、無限ループが発生します。
【補足】
①APIからのデータ取得は正常です。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。