flutter - Riverpod:列表提供程序未重建
问题描述
当' 的类型为时, Flutter Riverpod 不会通知Consumer
状态更改,而相同的实现对于其他类型也可以正常工作。StateNotifier
List
在这里,我提供了一个最小的可重现示例:
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ProviderScope(
child: MaterialApp(
home: MyHomePage(),
),
);
}
}
class CounterState extends StateNotifier<List<int>> {
static final provider = StateProvider(
(ref) => CounterState(),
);
int get last {
print('last');
return state.last;
}
int get length {
print('len');
return state.length;
}
// the body of this will be provided below
add(int p) {}
CounterState() : super(<int>[0]);
}
class MyHomePage extends ConsumerWidget {
@override
Widget build(BuildContext context, watch) {
void _incrementCounter() {
final _count = Random.secure().nextInt(100);
context.read(CounterState.provider.notifier).state.add(_count);
}
var count = watch(CounterState.provider.notifier).state.length;
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text(
'You have pushed the button this many times: $count',
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
child: Icon(Icons.add),
),
);
}
}
至于add
方法,我尝试了很多方式来实现它,但都没有奏效。
这是我尝试过的:
1:直接添加即可:
add(int p) {
state.add(p);
}
2:我也尝试了这个答案中建议的解决方案:
add(int p) {
state = [...state, p];
}
3:我试图完全销毁列表,并重新分配它:
add(int p) {
final _state = [];
// copy [state] to [_state]
for (var item in state) {
_state.add(item);
}
// empty the state
state = [];
// add the new element
_state.add(p);
// refill [state] from [_state]
for (var item in _state) {
state.add(item);
}
print(state.length); // it continues until here and prints
}
解决方案
首先,您没有创建正确的提供者来收听StateNotifier
. 你需要改变这个:
static final provider = StateProvider(
(ref) => CounterState(),
);
对此:
static final provider = StateNotifierProvider<CounterState, List<int>>(
(ref) => CounterState(),
);
有关不同类型的提供程序,请参阅 Riverpod 文档。
其次,您实际上并没有观察状态变化,而只是从通知程序中获取状态对象。
更改此行:
var count = watch(CounterState.provider.notifier).state.length;
对此:
final count = watch(CounterState.provider).length;
此外,您的增量方法对于StateNotifier
提供者也不正确。请更改此:
context.read(CounterState.provider.notifier).state.add(_count);
对此:
context.read(CounterState.provider.notifier).add(_count);
当状态改变时,它现在应该重建。但是,您确实需要一个add
实际更改状态对象本身的方法的实现。我建议您提到的第二个变体,我认为这是最好的方法:
add(int p) {
state = [...state, p];
}
推荐阅读
- json - 如何从验证数据更新一个 eloquent json 列而不覆盖列中存储的内容?
- reactjs - 如何使用 map 方法打印对象数组
- python - 如何在无服务器离线的子目录中引用处理程序?
- node.js - Docker 文件:错误找不到 package.json 文件
- python - 构造结构化数组时,元组和列表有什么区别?
- node.js - aws-serverless-express 连接错误 - EPIPE
- r - 将堆积条形图从 R 转换为 ggplot2
- ssl - WebLogic(使用 SSL)作为任何 WSGI Web 服务器的代理
- java - java如何知道调用哪个方法?
- stripe-payments - Stripe 创建令牌适用于无效的 cvv