search
LoginSignup
3

More than 1 year has passed since last update.

posted at

flutter_blocを使ってみる その4 - なぜEquatableを使うのか

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;
}

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
3