質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

Q&A

解決済

1回答

3236閲覧

FutureBuilderで無限ループが発生します。

pnbmg0044

総合スコア16

Flutter

Flutterは、iOSとAndroidのアプリを同じコードで開発するためのフレームワークです。オープンソースで開発言語はDart。双方のプラットフォームにおける高度な実行パフォーマンスと開発効率を提供することを目的としています。

0グッド

0クリップ

投稿2021/08/03 02:04

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からのデータ取得は正常です。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

以下の方法で自己解決しました。
①新たに初期処理として、API通信を複数行う関数を製造
②MyAppのreturnをFutureBuilderに設定し、引数futureに①の関数を指定
③データ取得が完了したら、MaterialAppを返す

Dart

1class MyApp extends StatelessWidget { 2 return FutureBuilder( 3 future: 初期処理関数, 4 builder: (BuildContext context, AsyncSnapshot snapshot) { 5 if (snapshot.connectionState == ConnectionState.waiting) { 6 return MaterialApp( 7 省略 8 ); 9 } 10 else { 11 if(snapshot.hasData){ 12 省略 13 return MaterialApp( 14 省略 15 ); 16 } 17 } 18 } 19 ) 20} 21 22class 初期処理関数 { 23) API通信1 24  API通信2 25   ... 26}

投稿2021/08/31 23:11

pnbmg0044

総合スコア16

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問