flutter_bloc
のEventとStateはなぜEquatable
を使うのか
Equatable
を使っている例
Equatable
は同じプロパティを持つインスタンスを同一として扱うオブジェクトです。
flutter_bloc
を用いるサンプルではStateとEventがEquatable
を継承することが多いです。
こちらのsampleでも以下のようにEquatable
を使っています。
abstract class TodosEvent extends Equatable {
TodosEvent([List props = const []]) : super(props);
}
abstract class TodosState extends Equatable {
TodosState([List props = const []]) : super(props);
}
Equatable
を使う理由
StateでEquatable
を使う理由
flutter_bloc
では異なるStateが通知された場合にのみUIをリビルドします。なので内容が同じであるStateを同一視したいのでEquatable
を使います。
Equatable
を使わない場合、同じであるはずのStateを受け取った場合にもhashCode
が違うので異なるStateと認識されて無駄なリビルドがされてしまいます。
EventでEquatable
を使う理由
例えばBLoCのtransformEvents
をオーバーライドしてdebounceさせる等、同じEventとして認識させたいことがあります。その際にEquatable
を用います。そのような扱いをしない場合にもEquatable
を用いる例が多く見られますが、これは慣習的なものなのかもしれません。
StateでもEventでも、同じプロパティを持つインスタンスを同一視したい場合にEquatable
を使います。
Equatable
の説明
Equatable
について少し詳しく説明します。
equatable
パッケージは同じプロパティを持つインスタンスを同一視させるEquatable
オブジェクトを提供します。
下に記すPerson
Classにて、次の演算はtrueになります。
print(Person(name: "Bob", age: 24) == Person(name: "Bob", age: 24)); // true
class Person extends Equatable {
final String name;
final int age;
Person({
@required this.name,
@required this.age
});
@override
List<Object> get props => [name, age];
}
これをEquatable
を使わずに書くと以下のようになります。
==
とhashCode
を上書きするコードを追加しています。
hashCode
でXORを使う理由はこちらの記事を参照してください。
class Person {
final String name;
final int age;
Person({
@required this.name,
@required this.age,
});
@override
bool operator ==(Object o) {
if (identical(this, o)) return true;
return o is Person && o.name == name && o.age == age;
}
@override
int get hashCode => name.hashCode ^ age.hashCode;
}