⛳
【Flutter ✖️ Riverpod】buildメソッド内で画面遷移する方法
buildメソッド内で、画面遷移したい・・・
と思って下記のコードを書いた事があるはずです
buildメソッド
@override
Widget build(BuildContext context, WidgetRef ref) {
Navigator.push(MaterialPageRoute...);
}
でも、これってエラーになるんですよね。
Error: The following assertion was thrown while dispatching notifications for GoRouterDelegate:
setState() or markNeedsBuild() called during build.
UIを構築中に画面遷移するなって事なんでしょうね。
まぁ、ここで画面遷移とかダイアログ出したい
気持ちは痛いほど分かります。
もし、するならinitState上でFuture処理をすると良いよって記事があったので
よかったら参考にしてみてね。
なんかinitState上でFuture処理すると最後に処理が回るらしい。
なるほど、だからエラーにならんわけだ。
@override
void initState() {
super.initState();
Future(() {
Navigator.push(context, MaterialPageRoute(builder: (context) {
return ThirdPage();
}));
});
}
参考:
本命はRiverpod
ということで、今回はriverpodを使ってどうやるのか
という事ですが・・・
下記のコードでなんとなく理解して下さいmm
final userInfoFutureProvider = FutureProvider<bool>((ref) async {
print('userInfoFutureProviderスタート');
await Future.delayed(const Duration(seconds: 2));
return true;
});
buildメソッド
@override
Widget build(BuildContext context, WidgetRef ref) {
ref.listen(userInfoFutureProvider, (previous, next) async {
print('listen発火');
context.go('/login');
print('画面遷移済み');
});
return const Scaffold();
}
うん、例が最悪な気がする。ということで、公式の方を見て下さいねmm
どうやら、ref.listenを使用すると、buildメソッド内でも、
問題なくcontext.goとかnavigatorとかダイアログをぶち込むことが出来るらしい。知らんけど。
理由はよく分からん。
普通はElevatedButtonとかで呼び出すんかなぁとか思ってたけど、逆に
ElevatedButtonとかでは呼び出すなって書いてるから不思議よねぇ。
まぁ、そっちは基本的にref.read使うから別に不思議でもないかぁ。
ということで、ref.listenを使用すると画面遷移できるらしいから、ぜひ使ってみてちょ。
Discussion