StateProviderを使っても良かったんだけど、
こんなやり方しかないのか?
Futureで返すから、thenで受けなくちゃいけなのが、面倒、、
HookConsumerWidget で、初めて、useEffectを使ってみたよ、、(これで良いのかは不明)
class LoginPage extends HookConsumerWidget { const LoginPage({Key? key, required this.title}) : super(key: key); final String title; @override Scaffold build(BuildContext context, WidgetRef ref) { debugPrint('LoginPage build'); final notifier = ref.watch(loginStateNotifierProvider.notifier); final _userNameTextCtl = useTextEditingController(); useEffect(() { notifier.getUname().then( (value) { _userNameTextCtl.text = value; //初期値をセット debugPrint('LoginPage build2' + value); }); },const[]); final errorMessage = ref.watch(errorMessageProvider); final _pwdTextCtl = useTextEditingController(); final FocusNode _userNameFocusNode = useFocusNode(); final FocusNode _passwordNameFocusNode = useFocusNode(); return Scaffold( appBar: AppBar( title: Text(title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(errorMessage, style: const TextStyle(color: Colors.red)), TextField( controller: _userNameTextCtl, decoration: const InputDecoration( filled: true, labelText: 'Username', ), focusNode: _userNameFocusNode, ), const SizedBox(height: 10.0), TextField( controller: _pwdTextCtl, decoration: const InputDecoration( filled: true, labelText: 'Password', ), focusNode: _passwordNameFocusNode, obscureText: true, ), ButtonBar( children: <Widget>[ ElevatedButton( child: const Text('ログイン'), onPressed: () { notifier.readData( _userNameTextCtl.text, _pwdTextCtl.text).then( (loginStatus) { // debugPrint('LOGIN:' + loginStatus.accessToken); Navigator.push(context, MaterialPageRoute(builder: (context) => ScheduleList(loginStatus: loginStatus))); } ).onError((error, stackTrace) { // _userNameTextController.clear(); _pwdTextCtl.clear(); }); }), ], ), ], ), ), ); } }
login_view_model.dart (コントローラー)
// StateNotifierProviderとLoginNotifierを使ったもの class LoginStateNotifier extends StateNotifier<LoginState> { final Ref ref; LoginStateNotifier(this.ref) : super(const LoginState()) { // debugPrint("init LoginStateNotifier"); } // ユーザ名取得 (from FlutterSecureStorage) Future<String> getUname() async { const storage = FlutterSecureStorage(); return await storage.read(key: "uname") ?? ''; } //データ読み込み処理 Future<LoginState> readData(name, password) async { LoginState loginState = await Repository().login(name, password) .onError((error, stackTrace) async { ref.watch(errorMessageProvider.notifier).state = "ログインに失敗しました"; throw Exception(error.toString()); }); state = state.copyWith( //stateを更新します isSaseki: loginState.isSaseki, syokuinCode: loginState.syokuinCode, accessToken: loginState.accessToken, refreshToken: loginState.refreshToken, ); // 抽出条件の初期化 ref.read(scheduleListWhereCondProvider.state).update( (state) => state.copyWith( syokuinCode: loginState.syokuinCode, isSaseki: loginState.isSaseki, dateFrom: DateTime.now(), dateTo: DateTime.now(), visitStatus: 'all', selectType: 'helper', // TODO 初期値は設定可能とする(ヘルパー、サ責、利用者) selectTypeCode: loginState.syokuinCode )); return loginState; } } final loginStateNotifierProvider = StateNotifierProvider((ref) => LoginStateNotifier(ref));