我正在創建一個 Flutter 應用程式。我已將 BloC 添加到我的管理狀態專案中。我創建了一個包含資料的串列。我想使用“添加”按鈕手動將專案添加到 ListView。
我寫了一個代碼:
我的物品肘
class ItemCubit extends Cubit<List<Item>> {
ItemCubit() : super([]);
void addItem(item){
state.add(item);
emit(state);
}
}
帶有 Provider 的專案頁面:
class SearchPage extends StatelessWidget {
const SearchPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BlocProvider(
create: (_) => ItemCubit(),
child: Search(),
),
);
}
}
我像這樣在無狀態小部件中呼叫 BlocBuilder:
body: BlocBuilder<MarketCubit, List<Market>>(
builder: (context, items) => TabBarView(...))
所以當我從 state 呼叫我的函式時:
Item item = Item(1, 'Item 1');
ElevatedButton(onPressed:(){
context.read<ItemCubit>().addItem(item);
}, child: Text('Add Item')),
ListView 不會更新。什么問題?非常感謝!
uj5u.com熱心網友回復:
ItemCubit 類超類不持有您的狀態。你應該管理自己的狀態。所以,我說的是在 ItemCubit 類中創建串列變數,每次呼叫 addItem 方法將專案添加到此串列并發出此串列。
您的 Cubit 類應如下所示;
abstract class ItemState {
const ItemState();
}
class ItemInitial extends ItemState {
const ItemInitial();
}
class ItemStateUpdatedList extends ItemState {
const ItemStateUpdatedList({required this.list});
final List<Item> list;
}
class ItemCubit extends Cubit<ItemState> {
ItemCubit() : super(const ItemInitial());
final List<Item> myItemList = [];
void addItem(item){
myItemList.add(item);
emit(ItemStateUpdatedList(list: myItemList));
}
}
body: BlocBuilder<ItemCubit, ItemState>(
builder:(context, state) {
if(state is ItemStateUpdatedList){
final list = state.list;
return TabBarView(...);
}
return const SizedBox.shrink();
},
)
uj5u.com熱心網友回復:
問題是您只是將專案添加到狀態并重新發出相同的(修改過的)串列。當你呼叫emit()時,Bloc本質上會檢查狀態物件的值,看它是否是一個新物件,如果它與上一個狀態“相同的串列”,它什么都不做。這是令人困惑的,因為即使您向串列中添加了一個新值,它在某種意義上仍然是同一個物件,只是具有一個新值。
因此,如果您只是創建一個新串列而不是修改原始串列并發出它,那么應該有一個簡單的修復方法。
例如,這應該可以解決問題:
emit([...state, newValue])
或者
final newList = List.from(state)..add(newValue);
emit(newList);
(我無法在 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,
);
}
如果狀態只是一個串列,那么這可能是不必要的,但是如果您發現自己想要向狀態添加屬性,那么這是一個很好的模式。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/386364.html
