【Flutter】前回入力したデータが残ってしまうバグの対策方法

こんにちは、株式会社Pentagonでアプリ開発をしている石渡港です。
https://pentagon.tokyo

今回はFlutterで前回入力したデータが残ってしまうバグの対策方法について調査しました。

その結果、対策方法がまとまりました。

【この記事を読むメリット】

  • Flutterで前回入力したデータが残ってしまうバグの対策方法がわかる

【こんな方に参考にしていただきたい】

  • Flutter開発初心者

【調査の動機】
弊社で開発中プロジェクトで前回入力したデータが残ってしまうバグが多発しているため、対策をまとめました。

【調査結果】

  • autoDisposeを利用すれば対処できることがわかりました。
目次

【結論】

今回は、バグが発生するコードと対策を施したコードをまとめました。

バグが発生するコード

弊社では、TextEditingController でテキストの入力を管理することが多いため、TextEditingController を利用してバグが発生する例を作成しました。

main.dart

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:test_input/home_screen.dart';

void main() {
  runApp(ProviderScope(child: MyApp()));
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: '入力テスト',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: HomeScreen(),
    );
  }
}

home_screen.dart

import 'package:flutter/material.dart';
import 'package:test_input/register_screen.dart';

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ホーム'),
      ),
      body: SafeArea(
        child: Center(
          child: MaterialButton(
            child: Text('登録画面へ'),
            onPressed: () {
              Navigator.push(context,
                  MaterialPageRoute(builder: (context) => RegisterScreen()));
            },
          ),
        ),
      ),
    );
  }
}

register_screen.dart

import 'package:flutter/material.dart';
import 'package:test_input/register_screen.dart';

class HomeScreen extends StatelessWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ホーム'),
      ),
      body: SafeArea(
        child: Center(
          child: MaterialButton(
            child: Text('登録画面へ'),
            onPressed: () {
              Navigator.push(context,
                  MaterialPageRoute(builder: (context) => RegisterScreen()));
            },
          ),
        ),
      ),
    );
  }
}

register_screen_model.dart

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

final registerScreenModelProvider =
    ChangeNotifierProvider<RegisterScreenModel>((ref) {
  return RegisterScreenModel();
});

class RegisterScreenModel extends ChangeNotifier {
  TextEditingController textEditingController = TextEditingController();
}

動きは画像を参照ください。

入力を終えたあと前画面に戻り、再度入力画面に進むと前回の入力が残ってしまっています。

https://i.gyazo.com/644e9b2776e601acb8558e3050736f4c.gif

対策を施したコード

弊社の場合の多くは、autoDisposeの宣言をしていないことが多かったです。
また、autoDisposeの宣言をしていても、disposeメソッドに明確に定義をしていないこともありました。register_screen_model.dartを下記のように変更しました。

register_screen_model.dart

import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';

final registerScreenModelProvider =
    ChangeNotifierProvider.autoDispose<RegisterScreenModel>((ref) {
  return RegisterScreenModel();
});

class RegisterScreenModel extends ChangeNotifier {
  TextEditingController textEditingController = TextEditingController();

  @override
  void dispose() {
    textEditingController.dispose();
    super.dispose();
  }
}

動きは下記の通りです。

入力を終えて、再度入力画面に遷移すると値が消えていることがわかります。

https://i.gyazo.com/7195b5ed1fbabacec75b97efde136b91.gif

まとめ

  • ChangeNotifierProvider を利用しているときautoDispose で宣言することを忘れない
  • autoDispose で宣言を行わないと自動でdispose してくれない
採用情報はこちら
目次