Created
October 18, 2023 22:17
-
-
Save rizumita/2ee9668e8ce2be152980d073f036872c to your computer and use it in GitHub Desktop.
Using useReducer with StoreInjector
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
import 'package:flutter_hooks/flutter_hooks.dart'; | |
import 'package:use_reducer_example/store_injector.dart'; | |
import 'reducer.dart'; | |
final itemsForDropdown1 = ['A', 'B', 'C']; | |
final itemsForDropdown2 = ['1', '2', '3']; | |
class MyFormUseReducerWithStoreInjectorView extends HookWidget { | |
const MyFormUseReducerWithStoreInjectorView({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
final MyFormStore store = useReducer( | |
reducer, | |
initialState: MyFormState(GlobalKey<FormState>(), useTextEditingController()), | |
initialAction: const ResetAction(), | |
); | |
return StoreInjector(store: store, child: const _Form()); | |
} | |
} | |
class _Form extends StatelessWidget { | |
const _Form(); | |
@override | |
Widget build(BuildContext context) { | |
final state = StateModel.of<MyFormState>(context); | |
return Form( | |
key: state.formKey, | |
child: Center( | |
child: Column( | |
children: [ | |
if (!state.isFinished) const _Dropdown1View(), | |
if (state case MyFormState(:final dropdown1Value?, textInput: null)) ...[ | |
const _TextInputField(), | |
const _SubmitTextInputButton(), | |
], | |
if (state case MyFormState(textInput: final textInput?, dropdown2Value: null)) ...[ | |
Text(textInput), | |
const _Dropdown2View(), | |
], | |
if (state | |
case MyFormState(:final dropdown1Value?, :final textInput?, error: null, :final dropdown2Value?)) ...[ | |
Text('Dropdown 1: $dropdown1Value'), | |
Text('Text Input: $textInput'), | |
Text('Dropdown 2: $dropdown2Value'), | |
const _ResetButton(), | |
], | |
], | |
), | |
), | |
); | |
} | |
} | |
class _Dropdown1View extends StatelessWidget { | |
const _Dropdown1View({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
final dropdown1Value = StateModel.selectOf<MyFormState, String?>(context, select: (state) => state.dropdown1Value); | |
return DropdownButton<String>( | |
value: dropdown1Value, | |
items: itemsForDropdown1.map((item) => DropdownMenuItem<String>(value: item, child: Text(item))).toList(), | |
onChanged: (value) => Dispatcher.of<MyFormAction>(context).dispatch(Dropdown1ChangedAction(value!)), | |
); | |
} | |
} | |
class _TextInputField extends StatelessWidget { | |
const _TextInputField({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
final textInputController = | |
StateModel.selectOf<MyFormState, TextEditingController>(context, select: (state) => state.textInputController); | |
return TextFormField( | |
controller: textInputController, | |
validator: (value) { | |
Dispatcher.of<MyFormAction>(context).dispatch(const ValidateTextInputAction()); | |
return StateModel.of<MyFormState>(context).error; | |
}, | |
); | |
} | |
} | |
class _SubmitTextInputButton extends StatelessWidget { | |
const _SubmitTextInputButton({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return ElevatedButton( | |
onPressed: () => StateModel.of<MyFormState>(context).formKey.currentState!.validate(), | |
child: const Text('Submit'), | |
); | |
} | |
} | |
class _Dropdown2View extends StatelessWidget { | |
const _Dropdown2View({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
final dropdown2Value = StateModel.selectOf<MyFormState, String?>(context, select: (state) => state.dropdown2Value); | |
return DropdownButton<String>( | |
value: dropdown2Value, | |
items: itemsForDropdown2.map((item) => DropdownMenuItem<String>(value: item, child: Text(item))).toList(), | |
onChanged: (value) => Dispatcher.of<MyFormAction>(context).dispatch(Dropdown2ChangedAction(value!)), | |
); | |
} | |
} | |
class _ResetButton extends StatelessWidget { | |
const _ResetButton({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return ElevatedButton( | |
onPressed: () => Dispatcher.of<MyFormAction>(context).dispatch(const ResetAction()), | |
child: const Text('Reset'), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment