我陷入了使用通用类型作为 Cubit 状态的问题。问题在于 Cubit 状态的不变性以及无法为泛型类型调用
copyWith
。基于 ChangeNotifier 的类似实现不会导致问题,因为我们可以改变返回的状态。
例如,我创建了一个具有通用状态的基本 Cubit,我计划对其进行扩展。然后我通过添加一个字段和 copyWith() 来实现通用类型的肘状态。
abstract class BasePageCubit<TParams extends BasePageParams>
extends Cubit<TParams> {
BasePageCubit({
required TParams initialState,
}) : super(initialState);
@mustCallSuper
void initialise() {
emit(state);
}
@protected
void markLoaded() {
emit(
**state.copyWith(isLoading: false)**,
);
}
}
@CopyWith()
class DataParams<TData> extends BasePageParams {
TData data;
DataParams({
required this.data,
super.isLoading = true,
super.pageError,
});
}
显然,我不能在 BasePageCubit 中使用
state.copyWith(isLoading: false)
,但我没有看到任何其他方法来实现与从 BasePageCubit 继承的 Cubit 一起使用的可扩展逻辑。一般来说,无论可用的类字段如何,我都需要通用 copyWith() 。这是 Dart 类型系统的基本限制,还是有任何解决方法?也许我误解了带有继承的 Bloc 模式?
我使用
Equatable
而不是 @CopyWith
注释。
使用下面的代码将允许您拥有通用状态。
abstract class BasePageCubit<TData> extends Cubit<DataParams<TData>> {
BasePageCubit({
required DataParams<TData> initialState,
}) : super(initialState);
void initialise() {
emit(state);
}
void markLoaded() {
emit(state.copyWith(isLoading: false));
}
}
class DataParams<TData> extends BasePageParams {
final TData data;
const DataParams({
required super.isLoading,
required this.data,
super.pageError,
});
@override
DataParams<TData> copyWith({
TData? data,
bool? isLoading,
String? pageError,
}) {
return DataParams(
data: data ?? this.data,
isLoading: isLoading ?? this.isLoading,
pageError: pageError ?? this.pageError,
);
}
@override
List<Object?> get props => [data, isLoading, pageError];
}
abstract class BasePageParams extends Equatable {
final bool isLoading;
final String? pageError;
const BasePageParams({
required this.isLoading,
this.pageError,
});
BasePageParams copyWith({
bool? isLoading,
String? pageError,
});
@override
List<Object?> get props;
}