Flutter Riverpod:FutureProvider 家族永远得不到解决
Flutter Riverpod: FutureProvider family never gets resolved
我是 Flutter Riverpod 包的新手。我实现了一个 FutureProvider 系列来根据日期时间参数(period
)处理异步 SDK 调用,非常严格地遵循官方 Riverpod 文档。
事件提供者(/providers/events.dart
)
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/event.dart';
const _platform = MethodChannel('com.eventSdk/sdk');
final eventsFamily =
FutureProvider.family<List<Event>, Map<String, int>>(
(ref, period) async {
List<Event> events = [];
String response = await _platform.invokeMethod(
'fetchEventHistory', {'from': period['from'], 'to': period['to']});
List rawEvents = jsonDecode(response);
for (var i = 0; i < rawEvents.length; i++) {
events.add(Activity.fromJson(rawEvents[i]));
}
log(events.toString()); // <- This successfully logs the events, meaning the SDK call is successfully awaited and answers
return events;
});
小部件(/screens/stats.dart
)
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../providers/events.dart';
import '../../models/event.dart';
class StatsPage extends ConsumerWidget {
const StatsPage({Key? key, required this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context, WidgetRef ref) {
final Map<String, int> period = {
"from": 1609477684000, // epoch in milliseconds (int)
"to": DateTime.now().toUtc().millisecondsSinceEpoch // epoch in milliseconds (int)
};
AsyncValue<List<Event>> events = ref.watch(eventsFamily(period));
return events.when(
loading: () => const CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
data: (events) {
log(events.toString());
return const Text("Loading successful!");
});
}
}
提供程序中的 log
成功记录回预期的 SDK 输出,因此我假设 FutureProvider 系列没问题。
但是读取提供者的消费者小部件中的 log
从未被调用,并且小部件始终处于加载状态,因此提供者的承诺似乎从未得到解决。我在这里做错了什么?
我尝试了 ConsumerWidget
以及 ConsumerStatefulWidget
/ConsumerState
。也尝试过 events.value.toString()
,但似乎都没有解决。
问题很可能是因为 period
在 build
方法中。
试试这个:
class StatsPage extends ConsumerWidget {
const StatsPage({Key? key, required this.title}) : super(key: key);
final String title;
final Map<String, int> period = {
"from": 1609477684000, // epoch in milliseconds (int)
"to": DateTime.now().toUtc().millisecondsSinceEpoch // epoch in milliseconds (int)
};
@override
Widget build(BuildContext context, WidgetRef ref) {
AsyncValue<List<Event>> events = ref.watch(eventsFamily(period));
return events.when(
loading: () => const CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
data: (events) {
log(events.toString());
return const Text("Loading successful!");
});
}
}
我是 Flutter Riverpod 包的新手。我实现了一个 FutureProvider 系列来根据日期时间参数(period
)处理异步 SDK 调用,非常严格地遵循官方 Riverpod 文档。
事件提供者(/providers/events.dart
)
import 'dart:convert';
import 'dart:developer';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../models/event.dart';
const _platform = MethodChannel('com.eventSdk/sdk');
final eventsFamily =
FutureProvider.family<List<Event>, Map<String, int>>(
(ref, period) async {
List<Event> events = [];
String response = await _platform.invokeMethod(
'fetchEventHistory', {'from': period['from'], 'to': period['to']});
List rawEvents = jsonDecode(response);
for (var i = 0; i < rawEvents.length; i++) {
events.add(Activity.fromJson(rawEvents[i]));
}
log(events.toString()); // <- This successfully logs the events, meaning the SDK call is successfully awaited and answers
return events;
});
小部件(/screens/stats.dart
)
import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../providers/events.dart';
import '../../models/event.dart';
class StatsPage extends ConsumerWidget {
const StatsPage({Key? key, required this.title}) : super(key: key);
final String title;
@override
Widget build(BuildContext context, WidgetRef ref) {
final Map<String, int> period = {
"from": 1609477684000, // epoch in milliseconds (int)
"to": DateTime.now().toUtc().millisecondsSinceEpoch // epoch in milliseconds (int)
};
AsyncValue<List<Event>> events = ref.watch(eventsFamily(period));
return events.when(
loading: () => const CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
data: (events) {
log(events.toString());
return const Text("Loading successful!");
});
}
}
提供程序中的 log
成功记录回预期的 SDK 输出,因此我假设 FutureProvider 系列没问题。
但是读取提供者的消费者小部件中的 log
从未被调用,并且小部件始终处于加载状态,因此提供者的承诺似乎从未得到解决。我在这里做错了什么?
我尝试了 ConsumerWidget
以及 ConsumerStatefulWidget
/ConsumerState
。也尝试过 events.value.toString()
,但似乎都没有解决。
问题很可能是因为 period
在 build
方法中。
试试这个:
class StatsPage extends ConsumerWidget {
const StatsPage({Key? key, required this.title}) : super(key: key);
final String title;
final Map<String, int> period = {
"from": 1609477684000, // epoch in milliseconds (int)
"to": DateTime.now().toUtc().millisecondsSinceEpoch // epoch in milliseconds (int)
};
@override
Widget build(BuildContext context, WidgetRef ref) {
AsyncValue<List<Event>> events = ref.watch(eventsFamily(period));
return events.when(
loading: () => const CircularProgressIndicator(),
error: (err, stack) => Text('Error: $err'),
data: (events) {
log(events.toString());
return const Text("Loading successful!");
});
}
}