Flutter:如何将Riverpod组件的局部状态提升至类实例级别?
实现方案
因为HookConsumerWidget中的Hook(比如useState)只能在build方法内部调用,要将状态提升到类实例级别,我们可以通过延迟初始化类成员来持有Hook返回的状态对象,具体实现如下:
class Btn extends HookConsumerWidget { const Btn({super.key}); // 延迟初始化,持有useState返回的状态对象 late final State<bool> isLoading; void onPressed() { // 避免重复触发加载 if (!isLoading.value) { isLoading.value = true; } } @override Widget build(BuildContext context, WidgetRef ref) { // 在build中初始化Hook状态,赋值给类成员 isLoading = useState(false); final counter = ref.watch(counterProvider); final counterNotifier = ref.read(counterProvider.notifier); useEffect(() { if (isLoading.value) { Future.delayed(const Duration(seconds: 1), () { isLoading.value = false; counterNotifier.reset(); }); } return null; }, [isLoading.value]); return ElevatedButton.icon( // 加载状态下禁用按钮 onPressed: isLoading.value ? null : onPressed, icon: isLoading.value ? const CircularProgressIndicator() : Container(), label: Text(isLoading.value ? "Loading" : "$counter"), ); } }
关键说明:
- 使用
late final State<bool> isLoading;延迟初始化类成员,确保能在build方法中拿到useState返回的状态对象,同时保证整个类实例生命周期内状态对象的一致性。 - 在
onPressed方法中增加状态判断,避免用户重复点击触发多次加载逻辑。 - 按钮的
onPressed属性根据isLoading.value动态设置为null(禁用)或onPressed方法,和原逻辑保持一致。
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

