Freezedの使い方


はじめにFreezedとは

簡単に言えばコピーメソッド等を含むImmutable(不変)なクラスを生成することができるパッケージのこと
Freezedでコードを生成することで便利なメソッドがいくつか使用できるようになる。

・copyWith nullを割り当てることが可能な複製メソッド ・== 同値であることの確認 ・toString 文字列化した時の結果 ・fromJson Mapからの変換 ・toJson Mapへの変換

上記のメソッドを使用して開発を楽にしましょう!

Freezedの使用方法

インストール

pubspec.yaml
dependencies:
  // @freezed などを使うために必須
  freezed_annotation:

dev_dependencies:
  //コード生成するために必要
  build_runner:
  freezed:
  // fromJson/toJson を生成させたい場合に必要になる
  json_serializable:

Freezedクラスの書き方

例として、友人の情報をまとめたFriendクラスをfriend.dartファイルを作成して、
そこに定義していく。

friend.dart
import 'package:freezed_annotation/freezed_annotation.dart';
// {ファイル名}.freezed.dart と書く
part 'friend.freezed.dart';

//Freezed特有の書き方なので、スニペットを用意するのが良い
@freezed
class Friend with _$Friend { 
  const factory Friend({ 
    /// 友人の名前
    required String name, //requiredで必須項目にする
  }) = _Friend; 
}

上記のコードのようにプロパティを必須項目にするには定義するプロパティの前にrequiredを記述する。
他にもnull許容にする場合、デフォルト値を設定する場合には下記のようにする。

null許容
  String? name
デフォルト値
  @Default('qiita君') String name

Freezedなクラスの定義が完了したら次にターミナルで下記のコマンドを入力し
Build Runnerの機能を使用し、コードを生成する。

ターミナル
  flutter pub run build_runner build 

Freezedクラスの修正や変更があった時などに、変更ごとに上記のコードを入力するのが面倒だと思います、そのためにファイルの更新を検知して自動で再生成してくれるコマンドも用意されています。
簡単です。上記のコードの最後のbuildをwatchに変えるだけ!

ターミナル
  flutter pub run build_runner watch

コードを生成してからそれだけで終了せず、監視を行ってくれます。

Freezedクラスを編集してコード生成をすると、古い生成済みファイルと競合しエラーが発生することがあります。
delete-conflicting-outputs オプションを付けることで、競合ファイルを削除して再生成してくれます。

ターミナル
  flutter pub run build_runner watch --delete-conflicting-outputs

Jsonから変換 または Jsonへの変換 をするために(fromJson/toJson)

Jsonから変換 Jsonへ変換するためのメソッドを生成するためには
Freezedだけではできないので 最初にpubspec.yamlに記入した json_serializable を使用し生成する。

JSON相互変換メソッドを生成させるには以下の2行を追加します。

  1. part 'friend.g.dart' を追加
  2. fromJson用のfactoryコンストラクタを追加
friend.dart
import 'package:freezed_annotation/freezed_annotation.dart';

part 'friend.freezed.dart';
part 'friend.g.dart'; // 追加

@freezed
class Friend with _$Friend {
  const factory Friend({
    required String name,
  }) = _Friend;

  // {} ではなく =>(アロー)を使ってください
  factory Friend.fromJson(Map<String, dynamic> json) => _$FriendFromJson(json);
}

これで、 fromJson, toJson 両方のメソッドが生成されるようになりました!

リントツールでのエラーが出る場合の対処方法

使用しているリントツールによっては、「コードがおかしいですよ」と怒られることもあるので、その場合は下記のように、 analysis_options.yaml で生成ファイルを対象外にしましょう。

analysis_options.yaml
analyzer:
  exclude:
    - "**/*.freezed.dart"
    - "**/*.g.dart"

今回参考にさせて頂いた記事

主にRiverpodの使い方など本当にわかりやすく書かれています、
今回の記事は以下の記事のほんの一部に過ぎないので、
ぜひ参考にしてみて下さい!