Site cover image
日々記録

Freezedメモ

依存関係の追加

pubspec.yamlファイルに必要なパッケージを追加。

dependencies:
  flutter:
    sdk: flutter
  freezed_annotation: ^2.4.1
  json_annotation: ^4.8.1

dev_dependencies:
  flutter_test:
    sdk: flutter
  build_runner: ^2.4.6
  freezed: ^2.4.5
  json_serializable: ^6.7.1

モデルクラスの作成

import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:json_annotation/json_annotation.dart';

part 'user.freezed.dart';
part 'user.g.dart';

@freezed
class User with _$User {
  const factory User({
    required String id,
    required String name,
    @Default('') String email,
    int? age,
  }) = _User;

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

コード生成の実行

コード作成後に自動生成のコマンドを実行

flutter pub run build_runner build

変更を監視して自動生成したい場合

flutter pub run build_runner watch

生成されたコードの確認

user.freezed.dartuser.g.dartの2つのファイルが自動生成

モデルの使用例

// インスタンスの作成
final user = User(id: '1', name: 'John Doe', email: '[email protected]', age: 30);

// copyWithを使用した不変の更新
final updatedUser = user.copyWith(name: 'Jane Doe', age: 25);

// JSONへの変換
final json = user.toJson();

// JSONからの変換
final userFromJson = User.fromJson(json);

// パターンマッチング
void checkUser(User user) {
  user.when(
    (id, name, email, age) {
      print('User $name with ID $id, email $email and age $age');
    },
  );
}

freezedの便利な機能

イミュータブルなオブジェクト
  • copyWith()を使用して新しいインスタンスを作成
等価性の比較
  • ==演算子とhashCodeが自動生成される
パターンマッチング
  • when(), maybeWhen(), map(), maybeMap()メソッド
ユニオン型(シールドクラス
@freezed
class Result<T> with _$Result<T> {
  const factory Result.success(T value) = Success<T>;
  const factory Result.error(String message) = Error<T>;
}

トラブルシューティング

flutter pub run build_runner build --delete-conflicting-outputs

VSCodeでのカスタムスニペットの作成

Preferences: Configure User Snippetsでdart.jsonに下記を追加

"Freezed Model": {
  "prefix": "fzmodel",
  "body": [
    "import 'package:freezed_annotation/freezed_annotation.dart';",
    "import 'package:json_annotation/json_annotation.dart';",
    "",
    "part '$TM_FILENAME_BASE.freezed.dart';",
    "part '$TM_FILENAME_BASE.g.dart';",
    "",
    "@freezed",
    "class ${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}} with _$${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}} {",
    "  const factory ${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}}({",
    "    required ${2:String} ${3:id},",
    "    $0",
    "  }) = _${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}};",
    "",
    "  factory ${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}}.fromJson(Map<String, dynamic> json) =>",
    "      _$${1:${TM_FILENAME_BASE/(.*)/${1:/pascalcase}/}}FromJson(json);",
    "}"
  ],
  "description": "Create a new Freezed model class"
}

これを設定したら、新しいDartファイルで fzmodel と入力してTabキーを押すと、テンプレートが挿入されます。

コマンドラインから生成する場合

# 単一のファイルを生成
flutter pub run build_runner build --build-filter="lib/models/user.dart"

# 変更を監視して自動生成
flutter pub run build_runner watch

VSCode固有のショートカット

  • Ctrl+Shift+B (Windows/Linux) または Cmd+Shift+B (Mac): タスクを実行(build_runnerコマンドをタスクとして設定可能)
  • F5: デバッグ実行