Как мне получить состояние загрузки/спиннер с помощью уведомления о состоянии flutter riverpod, ref watch и asyncvalue?

У меня есть приведенный ниже пример, который обновляет данные, но не дает счетчика, как ожидалось. Я попытался использовать ref.listen, чтобы переключиться на асинхронную загрузку, я попытался выполнить ожидание перед вызовом, хотя это не имело смысла.

Я попробовал ref.refresh, ref.invalidate... Ожидаемое поведение : откройте приложение, посмотрите счетчик, нажмите кнопку, снова посмотрите счетчик, прежде чем текст изменится. Фактическое поведение : откройте приложение, увидите счетчик, нажмите кнопку, текст изменится, а счетчик не отображается. также см. https://github.com/neiljaywarner/riverpod_watching_dep_no_spinner_sample . Я использую флаттер 3.0.5 и hooks_riverpod: ^2.0.0-dev.9.

      import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

void main() => runApp(ProviderScope(child: MyApp()));

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(title: 'Riverpod Spinner Demo',
      theme: ThemeData(primarySwatch: Colors.blue), home: MyHomePage());
}

class MyHomePage extends ConsumerWidget {

  @override
  Widget build(BuildContext context, WidgetRef ref) => Scaffold(
      appBar: AppBar(title: const Text('Riverpod Spinner Question'),),
      body: ref.watch(futureProvider).when(data: (data) => Column(
        children: [
          ElevatedButton(onPressed: () => ref.read(paramProvider.notifier).state = 'new value',
              child: const Text('pretend update')),
          Text(data)],
      ),
          error: (_,__) => const Text('something went wrong'),
          loading: () => const CircularProgressIndicator())
  );
}

final paramProvider = StateProvider((ref) => 'Initial value');

final futureProvider = FutureProvider.autoDispose<String>((ref) async {
  String parameter = ref.watch(paramProvider);
  return pretendApiCall(parameter);
});
Future<String> pretendApiCall(String parameter) async {
  await Future.delayed(const Duration(seconds: 3));
  return parameter;
}

4 ответа

Ах.

      var asyncValue = ref.watch(futureProvider);
return Scaffold(
  appBar: AppBar(title: const Text('Riverpod Spinner Question'),),
  body: asyncValue.when(data: (data) {
    if (asyncValue.isRefreshing) return const CircularProgressIndicator();
    return Column(
    children: [
      ElevatedButton(onPressed: () => ref.read(paramProvider.notifier).state = 'new value',
          child: const Text('pretend update')),
      Text(data)],
  );
  },

Я думаю, вы видите это нарушение измененного поведения:

Прерывание После того, как поставщик выдал AsyncValue.data или AsyncValue.error, этот поставщик больше не будет выдавать AsyncValue.loading. Вместо этого он повторно выдаст последнее значение, но со свойством AsyncValue.isRefreshing, равным true.

Таким образом, поведение, которое вы описываете, является дизайном.

ах - настоящий ответ от самого Реми https://github.com/rrousselGit/riverpod/discussions/1600 "Это поведение изменилось на главной ветке

Просто дождитесь релиза, и ваша проблема должна исчезнуть"

Попробуйте обновить свойFlutter 3.3.0И используяhooks_riverpod: ^1.0.4

Другие вопросы по тегам