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

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

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

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

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

意見交換

4回答

503閲覧

flutter、dart 初回描画時のみ実行される

drop8

総合スコア3

Flutter

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

Dart

Dartは、Googleによって開発されたJavaScriptの代替となることを目的に作られた、ウェブ向けのプログラミング言語である。

0グッド

0クリップ

投稿2024/04/11 02:29

編集2024/04/11 02:33

flutter学習中です。

テーマ、知りたいこと

任意の画面の初回描画時のみ処理を書いていますが(ボタンを押した後は実行されない)、こういった際は、StatefulWidgetのinitState()を使用するのが一般的でしょうか?
又、他に選択肢はあるのでしょうか?

背景

色々なサイトで学習していると現在はriverpodを使用するのが主流と書いてあり、StatefulWidgetはあまり使わないと書いてます。riverpodで書く事は出来るのでしょうか?また、riverpod(他の方法でも)に置き換えることは妥当なのでしょうか?

状況

念の為に、下にコードも出します。簡略化しているので動作しなければご容赦下さい。
CRUD対応のツイッター的なアプリを作っています。

*入力画面から遷移して来る
*初回描画にfirestoreにデータを作成。
*登録完了を表示
*ボタンを押して一覧画面へ遷移

このコードの中でinitState()を使用しないと、初回描画とボタンを押した際で2回
await db.collection('tweets').doc().set(
{
'userName': widget.tweet_username,
'text': widget.tweet_text,
},
が実行されてしまいました。

よろしくお願いします。

dart

1import 'package:flutter/material.dart'; 2import 'package:cloud_firestore/cloud_firestore.dart'; 3 4class TweetAddexec extends StatefulWidget { 5 final String tweet_username; 6 final String tweet_text; 7 8 const TweetAddexec({ 9 Key? key, 10 required this.tweet_username, 11 required this.tweet_text, 12 }) : super(key: key); 13 14 15 _TweetAddexecState createState() => _TweetAddexecState(); 16} 17 18class _TweetAddexecState extends State<TweetAddexec> { 19 20 void initState() { 21 super.initState(); 22 23 final db = FirebaseFirestore.instance; 24 await db.collection('tweets').doc().set( 25 { 26 'userName': widget.tweet_username, 27 'text': widget.tweet_text, 28 }, 29 ); 30 } 31 32 33 Widget build(BuildContext context) { 34 return Scaffold( 35 backgroundColor: Colors.orange, 36 appBar: AppBar( 37 title: Text('登録完了'), 38 automaticallyImplyLeading: false, 39 ), 40 floatingActionButton: FloatingActionButton( 41 onPressed: () => GoRouter.of(context).push('/tweet/index'), 42 child: const Text('一覧画面へ'), 43 ), 44 ); 45 } 46} 47

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

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

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

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

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

回答4

#1

ta.fu

総合スコア1676

投稿2024/04/11 22:03

StatefulWidgetのinitState()を使用するのが一般的でしょうか?

StatefulWidgetを使っている場合は、管理している状態の初期化を行うにはinitStateをオーバーライドして実装するのが定石です。

現在はriverpodを使用するのが主流と書いてあり、StatefulWidgetはあまり使わないと書いてます。

一応状態管理に関しては、Flutter公式としては以下のページがあります。
https://docs.flutter.dev/data-and-backend/state-mgmt
https://docs.flutter.dev/data-and-backend/state-mgmt/options

簡単なものであれば、StatefulWidgetで感をつかむのはいいかもしれないですが、画面が複雑になったり、複数画面にわたるようなデータを取り扱うとかいった場合は、状態管理用のパッケージを利用する方が設計や実装が楽になります。

状況
このコードの中でinitState()を使用しないと、初回描画とボタンを押した際で2回

実装として間違っているように見えます。

db.collection('tweets').doc().setは非同期処理です。
この結果につてはinitState内でawaitで待つんじゃなくてFutureで保持しておいてその結果をFutureBuilderで利用するというのが通常の実装です。
Futureが完了した時点で登録完了を表示したり、ボタンを押せるような状態にするように実装したほうがいいと思います。

2回実行されるという点については、分かりません。
この実装で問題ないようには思えるのですが。

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

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

#2

drop8

総合スコア3

投稿2024/04/13 01:40

#1
丁寧なご回答ありがとうございます。 
あくまでStatefulWidgetの範囲内でなら、initStateを使用との事で。やはりriverpodなど状態管理パッケージを使用を見据えた作りにしていきたいです。

StatefulWidgetで調べてinitStateがでてくるんですが、riverpodでinitStateに相当するものが見つからないです。実装の際に初回描画フラグを準備して分岐させているんでしょうか。

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

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

#3

ta.fu

総合スコア1676

投稿2024/04/13 03:06

#2

riverpodでinitStateに相当するものが見つからないです。実装の際に初回描画フラグを準備して分岐させているんでしょうか。

正式推奨の方法は以下のような形なのかな。
https://riverpod.dev/ja/docs/essentials/eager_initialization

初期化方法というより、初期化タイミングを明示的に決めたいといった内容かも。

providerは初めてref.watchやref.readで使用されたときに初期化されるんで、初期化するタイミングを明示的に決めたいのであれば、利用されるウィジェットツリーのトップのどこかにその呼び出しを入れる。
それが上のドキュメントのようなやり方になるんだと思う。

ただ今回のケースでいうと、分岐させるというのは必要ないと思う。
上に書いた通り、初回呼び出し時に初期化が行われるので、それ以外は既に生成済みの情報を参照している感じになるので。

ただ#1 に書いた通り、非同期処理が入っているのでそれに対応した処理(実装)にする必要がある。

  • 補足
    個人的にprovider/riverpod好きではない、というかなんか難解でしっくりした感じに覚えづらいんで私はGetXという状態管理パッケージを使ってます。
    ただGetXは、こちらも曰くがあるらしいんですが。例えば状態管理以外の機能も詰め込みすぎだとか。他いろいろと。

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

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

#4

drop8

総合スコア3

投稿2024/04/13 04:48

初期化方法というより、初期化タイミングを明示的に決めたいといった内容かも。

これです!助かります!!
GetXも確認してみます。 ありがとうございます。

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

この意見交換はまだ受付中です。

会員登録して回答してみよう

アカウントをお持ちの方は

関連した質問