0

在以下代码段中, state.copyWith 函数不可用。

@freezed
class MyState with _$MyState {
  @JsonSerializable(fieldRename: FieldRename.snake, explicitToJson: true)
  const factory MyState({@Default(0) int counter,}) = _MyState;
  const factory MyState.initial({@Default(0) int counter}) = Initial;
  const factory MyState.loading() = Loading;
  const factory MyState.one() = One;
  const factory MyState.two() = Two;

  factory MyState.fromJson(Map<String, dynamic> json) =>
      _$MyStateFromJson(json);
}

class MyStateNotifier extends StateNotifier<MyState> {
  MyStateNotifier() : super(MyState.initial());

  Future<void> one() async {
    state = MyState.loading();
    await Future.delayed(Duration(seconds: 5));
    state.copyWith(counter: 1);
  }
}

但是,当我删除密封类时,copyWith 函数可用。

@freezed
class MyState with _$MyState {
  @JsonSerializable(fieldRename: FieldRename.snake, explicitToJson: true)
  const factory MyState({@Default(0) int counter,}) = _MyState;
  // const factory MyState.initial({@Default(0) int counter}) = Initial;
  // const factory MyState.loading() = Loading;
  // const factory MyState.one() = One;
  // const factory MyState.two() = Two;

  factory MyState.fromJson(Map<String, dynamic> json) =>
      _$MyStateFromJson(json);
}

class MyStateNotifier extends StateNotifier<MyState> {
  MyStateNotifier() : super(MyState());

  Future<void> one() async {
    await Future.delayed(Duration(seconds: 5));
    state.copyWith(counter: 1);
  }
}

我需要更改什么才能使第一个片段中的 copyWith 可用?

4

2 回答 2

1

如README 文档copyWith中所述,只有所有构造函数共有的属性才会生成方法。

You also can use copyWith with properties defined on all constructors...

想象一下,你有一个 的实例,你希望它有Loading什么方法?copyWith它没有属性,因此它不能有任何copyWith方法,因此所有类型的联合也不能。

但是,您可以使用模式匹配来调用copyWith正确类型的实例。

在你的例子中,这样的事情会起作用:

MyState myState = ...;

myState.maybeMap(
    initial: (v: Initial) => v.copyWith(counter: v.counter + 1),
    orElse: () => ...,
);

或使用when

MyState myState = ...;

myState.when(
    (int counter) => MyState.initial(counter + 1),
    loading: () => loading,
    one: () => one,
    two: () => two,
);
于 2021-06-05T10:42:57.877 回答
0

您可以访问 copyWith 方法,进行类型转换:

`if (state is CurrentState) { final myState = state as CurrentState }

myState.copyWith (...)`

于 2022-01-04T12:04:54.750 回答