我之前分别观察一些字符串和 bool 值的状态,如下所示:
var strSearchProvider = StateProvider<String>((ref) {
return "";
});
String strSearch = ref.watch(strSearchProvider ); // this works
这次我尝试制作一个包含字符串和 bool 值的简单对象:
class AppState {
String strSerach = "";
bool playing = false;
bool searching = false;
AppState();
}
var appStateProvider = StateProvider<AppState>((ref) {
return AppState();
});
现在我是这样看的:
// inside consumer buid method
AppState watchedState = ref.watch(appStateProvider);
// some codes ..
appbar: AppBar(
actions: !watchedState.searching
? [
Padding(
padding: const EdgeInsets.all(8.0),
child: IconButton(
icon: const Icon(Icons.search),
onPressed: () {
ref.read(appStateProvider.notifier).update((state) {
state.searching = true;
return state;
});
}),
)
]
: [
Padding(
padding: const EdgeInsets.all(8.0),
child: IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
ref.read(appStateProvider.notifier).update((state) {
state.searching = false;
return state;
});
}),
)
],
//the rest
但是当我按下搜索图标时没有任何反应,并且观看状态并未真正观看。
那我该怎么办呢?单独提供/观看所有内容是一个好习惯吗?
最佳答案
重点是您的状态对象应该是不可变的。当您考虑简单类型 int
、String
、bool
、double
时,一切都会按预期工作。但是一旦您创建了一个对象,例如集合或您自己的类,那么此时您应该注意它们的可变性。
要使您的类不可变,其所有字段都必须标记为final
。此外,您需要注意覆盖 hashCode
和 ==
。当有很多字段时更改此类对象的实例可能非常不方便。正是出于这些目的,创建了 freezed
或 equitable
包,它们为我们做了很多工作,包括有用的 copyWith
方法用于基于旧实例快速创建新实例。
对于 List
、Map
和 Set
等集合 - 它们本质上是可变 。因此,每当您需要更改状态(这是一个集合)时,您都必须创建该集合的一个新实例。例如,对于列表,执行此操作的简单方法是使用 spread (state = [...oldState];
) 或使用 List.of
方法。
尝试坚持这些方面,您的代码将响应:)
关于dart - 观察对象的状态,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77148346/