こんにちは、株式会社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();
}
動きは画像を参照ください。
入力を終えたあと前画面に戻り、再度入力画面に進むと前回の入力が残ってしまっています。
対策を施したコード
弊社の場合の多くは、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();
}
}
動きは下記の通りです。
入力を終えて、再度入力画面に遷移すると値が消えていることがわかります。
まとめ
ChangeNotifierProvider
を利用しているときautoDispose
で宣言することを忘れないautoDispose
で宣言を行わないと自動でdispose
してくれない