Open11

Flutterなんでもメモ

futaba3futaba3

Widget描画時に一回だけ行いたい処理で使う関数

  • StatefulWidget のinitState()
  • WidgetsBinding.instance.addPostFrameCallback()
  • flutter hooksのuseEffect()

それぞれの違いは処理が実行されるタイミング。処理を行いたいタイミングに応じて使い分ける。
initState()useEffect()はWidgetの描画が完了する前に読み込まれる。
WidgetsBinding.instance.addPostFrameCallback()はWidgetが描画されてから処理を実行してくれる。
例えばuseEffect()内でWidgetsBinding.instance.addPostFrameCallback()を利用すると、ウィジェットの再構築時に毎回Widget描画後の処理を実行できる。
https://zenn.dev/kirisimacreate/articles/8fe3c5da372170

futaba3futaba3

https://github.com/flutter/flutter/issues/22025

Cannot listen to inherited widgets inside HookState.initState. Use HookState.build instead

useEffect 内で直接 DefaultTabController.of(context) を呼び出しているために発生しています。useEffect は initState のタイミングで実行されるため、この時点では InheritedWidget にアクセスできません。

futaba3futaba3

pubを使って何らかファイル生成するときのコマンド

ex. flutter_svgでsvg画像を追加する時、freezedしたファイルを生成するとき、retrofitのAPIクライアントファイルを生成するときなど

flutter pub run build_runner build --delete-conflicting-outputs
futaba3futaba3

Riverpodのプロバイダ修飾子
.autoDispose → プロバイダの監視が終わったタイミングでプロバイダに自動でステートを破棄させることができるようになる。メモリリークを未然に防ぐことができる。
.family → プロバイダ外部の値を用いてプロバイダを作成できるようになる。ListViewの要素に画像などの表示するデータを渡したいとき、詳細に遷移した際にIDを渡したいときなどに使う。

futaba3futaba3

Flutter関係ないけどgitで追跡していたファイルを途中から追跡をやめたいとき
.gitignoreに追加するだけでなく対象ファイルのキャッシュを削除する必要がある

git rm --cached android/app/src/main/AndroidManifest.xml
git commit -m "Remove AndroidManifest.xml from version control"
futaba3futaba3

Riverpod
.readと.watch何が違うの

.read
ユーザーの操作によってトリガーされる関数内でよく使用される
しかし、以下のような記述があり、.readはリアクティブでないため、できるだけ使用しないことが推奨されている。.readは.watchか.listenを使用すると問題が発生する場合のために存在するので、可能であれば、.watchを利用するのが適切。

Using ref.read should be avoided as much as possible because it is not reactive.
It exists for cases where using watch or listen would cause issues. If you can, it is almost always better to use watch/listen, especially watch.

buildメソッドの中では使わない

https://riverpod.dev/docs/concepts/reading

ref.watchとref.readの違い
ref.watch():

プロバイダーの状態を監視しており、状態が変わるたびにウィジェットやクラスが再ビルドされます。
主にUI(ウィジェット)の中で使用され、リアクティブに状態を反映させたいときに便利です。
使う場面:
UIが状態に応じて動的に更新される必要があるとき。
例えば、APIの結果やユーザー入力に応じて画面を変えたい場合。
ref.read():

プロバイダーの値を一度だけ読み取ります。その後の状態変化を監視しません。
主に非同期処理やイベントハンドラの中で使います。リアクティブに再ビルドされる必要がない場面に適しています。

使う場面:
一度だけ状態を取得したい場合や、更新をトリガーしたい場合。
例えば、ボタンを押したときにAPIを叩くような場面で使います。
問題がref.watchからref.readに変更することで解決した理由
ref.watchは、プロバイダーが更新されるたびにそのウィジェットやクラスを再ビルドしようとします。そのため、非同期処理の結果などを監視したいわけではない場合、無駄にリビルドが発生し、パフォーマンスやロジックに影響が出る可能性があります。

futaba3futaba3

useAutomaticKeepAliveClient() タブを切り替えてもステートを保持してくれる