https://flutter.dev/docs/cookbook/networking/fetch-data
上記ページ最下部のComplete exampleなんですが、
全体的なつくりとして、
(1)
http通信で取得した文字列をfetchAlbum関数でAlbum型として取得(非同期なので
fetchAlbum関数の返り値はFuture<Album>型)
(2)
MyAppウイジェットをStatefullWidgetとして、MyAppStateクラスを用意、
そのMyAppStateクラスのフィールドして
Future<Album> futureAlbum;
を保持。つまりfutureAlbumが状態(state)。
(3)
MyAppStateクラスのbuildメソッド内でFutureBuilderウィジェットを使用。ということでFutureがコンプリートしたら得られたレスポンスのtitleフィールドを表示。
という感じだと思います。これ自体はこれで動いているので特に疑問は無いんですが、
これって状態としてfetchAlbum関数の返り値を保持する必要はあるのでしょうか?
つまりこのシンプルなケースならMyAppウィジェットはStatelessWidgetで、
FutureBuilderのfutureフィールドにfetchAlbum関数(の返り値)をセットする。つまり下記のコード。
import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; Future<Album> fetchAlbum() async { final response = await http.get('https://jsonplaceholder.typicode.com/albums/19'); if (response.statusCode == 200) { // If the server did return a 200 OK response, // then parse the JSON. //return Album.fromJson(json.decode(response.body)); var temp=json.decode(response.body); return Album(userId:temp['userId'],id:temp['id'],title:temp['title']); } else { // If the server did not return a 200 OK response, // then throw an exception. throw Exception('Failed to load album:${response.statusCode}'); } } class Album { final int userId; final int id; final String title; Album({this.userId, this.id, this.title}); factory Album.fromJson(Map<String, dynamic> json) { return Album( userId: json['userId'], id: json['id'], title: json['title'], ); } } void main() => runApp(MyApp()); class MyApp extends StatelessWidget { MyApp({Key key}) : super(key: key); @override Widget build(BuildContext context) { return MaterialApp( title: 'Fetch Data Example', theme: ThemeData( primarySwatch: Colors.blue, ), home: Scaffold( appBar: AppBar( title: Text('Fetch Data Example'), ), body: Center( child: FutureBuilder<Album>( future: fetchAlbum(), builder: (context, snapshot) { if (snapshot.hasData) { return Text(snapshot.data.title); } else if (snapshot.hasError) { return Text("${snapshot.error}"); } // By default, show a loading spinner. return CircularProgressIndicator(); }, ), ), ), ); } }
これでstate有りの時と同様の結果が出るんですが、それならStatefulWidgetにする必要あるのか?と思ってしまいます。FutureBuilder使うときはstateを用意すべき、みたいなことがあるんでしょうか?
じゃなくて、今回はシンプルな例だからたまたまstate無しでも問題無いが、例えば
- 一つのアプリ(画面)の中の複数の箇所(複数のウィジェット)で、取得したレスポンスを表示するなりしたい場合
- ボタンを押したら別のアルバムを取得して表示するようにしたい場合
上記のような場合stateを用意すべきなので今回のサンプルでもstate有りのサンプルを示している、ということでしょうか。
もう一つ、Flutterの状態管理に関して、Bloc、Scoped Model、Provider、Riverpod、Hooks、Reduxなどいろいろなライブラリが次々と出てきて、どれを勉強すれば良いのかよくわかりません。
全部勉強しないといけないのでしょうか?全部って相当なコストだと思うのですが(笑)、
結局目的は全て「状態管理」なので同じことを方法を変えてやろうとしているわけですよね。どれかひとつが圧倒的に便利、ということならそれで決まりでしょうし、そうでないのなら、どれかの選択肢で目的達成(問題解決)できればいいのではないか、と思うのですが。
(Hooksについてはreactでもあったような気がしますが、
Flutter公式では採用しない?わかりませんが、いろいろな話がありますよね。)
一番最初からFlutterをやっている人は全部キャッチアップして、それぞれの利点もわかっている、という方もおられると思うのですが、最近勉強を始めた人だと、もうすでに
「今はProviderですよね」
「いやRiverpodですよね(でも現時点で公式推奨はProvider)」
「Blocは古いですよね」
などの声がtwitterなどで見られます。(私自身Blocも全くわかってないのですが)
こういうのはどういう風に捉えれば良いのでしょうか。
結局「道具」であり、最終的にどれが推奨されるかは全くわからないし、結局どれがいいのかは自分で使ってみなければわからないので、とにかくいろいろ使ってみて便利だと思うものを見つけて採用しながら今後の流れを注視する、みたいなことですかね?
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/09/06 14:57
2020/09/06 15:19
2020/09/07 02:12
2020/09/07 02:14
2020/09/11 00:03