use*_*566 2 android flutter bloc
我正在创建一个 Flutter 应用程序。我在项目中添加了一个 BloC 以管理状态。我创建了一个包含数据的列表。我想使用“添加”按钮手动将项目添加到 ListView。
我写了一段代码:
我的物品 肘节
class ItemCubit extends Cubit<List<Item>> {
ItemCubit() : super([]);
void addItem(item){
state.add(item);
emit(state);
}
}
Run Code Online (Sandbox Code Playgroud)
提供者的项目页面:
class SearchPage extends StatelessWidget {
const SearchPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BlocProvider(
create: (_) => ItemCubit(),
child: Search(),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
我在 Stateless Widget 中调用 BlocBuilder,如下所示:
body: BlocBuilder<MarketCubit, List<Market>>(
builder: (context, items) => TabBarView(...))
Run Code Online (Sandbox Code Playgroud)
所以当我从状态调用我的函数时:
Item item = Item(1, 'Item 1');
ElevatedButton(onPressed:(){
context.read<ItemCubit>().addItem(item);
}, child: Text('Add Item')),
Run Code Online (Sandbox Code Playgroud)
ListView 不更新。什么问题?多谢!
问题是您只是将项目添加到状态并重新发出相同的(修改后的)列表。当你调用emit()时,Bloc本质上会检查状态对象的值,看看它是否是一个新对象,如果它与最后一个状态“相同的列表”,它将什么都不做。这很令人困惑,因为即使您向列表中添加了新值,但从某种意义上来说它仍然是同一个对象,只是具有新值。
因此,如果您只是创建一个新列表而不是修改原始列表并发出它,应该有一个简单的修复方法。
例如,这应该可以解决问题:
emit([...state, newValue])
Run Code Online (Sandbox Code Playgroud)
或者
final newList = List.from(state)..add(newValue);
emit(newList);
Run Code Online (Sandbox Code Playgroud)
(我在 bloc 文档中找不到对此进行解释的地方,但有许多问题线程讨论了它 - https://github.com/felangel/bloc/issues/2374)
本质上,状态应该是“不可变的”,所以如果你要发出一个新状态,你实际上应该为你要发出的任何东西创建一个新实例。我通常使用状态的方式是为 cubit 正在跟踪的任何状态提供一个带有最终字段的类,以及一个 copyWith 方法,可以轻松地使用任何修改的字段创建一个新实例:
YourCubitState{
final List stateList;
final otherField;
const YourCubitState({
this.stateList = [],
this.otherField,
});
YourCubitState copyWith({
List? stateList,
otherField,
}) =>
YourCubitState(
stateList: stateList ?? this.stateList,
otherField: otherField ?? this.otherField,
);
}
Run Code Online (Sandbox Code Playgroud)
如果状态只是一个列表,也许这是不必要的,但如果您发现自己想要向状态添加属性,那么这是一个很好的模式。
| 归档时间: |
|
| 查看次数: |
7185 次 |
| 最近记录: |