😸

FlutterのuseStreamを使うと何度もbuildが呼び出されてしまう

2023/03/02に公開
Stream<int> stopwatch() async* {
  int i = 0;
  while (true) {
    yield i++;
    await Future.delayed(const Duration(seconds: 1));
  }
}

class Home extends HookWidget {
  const Home({super.key});

  
  Widget build(BuildContext context) {
    final timer = useStream(stopwatch()).data ?? 0;

    return Scaffold(body: Center(child: Text(timer.toString())));
  }
}

これは単純な Stream を作成してそれを useStream で wrap するというコードですが、これはまともに動きません。

class Home extends HookWidget {
  const Home({super.key});

  
  Widget build(BuildContext context) {
    final timerStream = useMemoized(() => stopwatch());
    final timer = useStream(timerStream).data ?? 0;

    return Scaffold(body: Center(child: Text(timer.toString())));
  }
}

当たり前ですが、こうしましょう。
すごく当たり前のことですが、ハマりました。

FirebaseAuth を使う場合は、こう。

User? useCurrentUser(WidgetRef ref) {
  final userStream = useMemoized(() => FirebaseAuth.instance.authStateChanges());
  return useStream(userStream).data;
}
GitHubで編集を提案

Discussion