Skip to content

Instantly share code, notes, and snippets.

@rizumita
Created October 18, 2023 22:15
Show Gist options
  • Save rizumita/c608b8f87c41bda2348e4c172dee5f68 to your computer and use it in GitHub Desktop.
Save rizumita/c608b8f87c41bda2348e4c172dee5f68 to your computer and use it in GitHub Desktop.
reducer
import 'package:equatable/equatable.dart';
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
class MyFormState extends Equatable {
const MyFormState(
this.formKey,
this.textInputController, [
this.dropdown1Value,
this.textInput,
this.error,
this.dropdown2Value,
]);
final TextEditingController textInputController;
final GlobalKey<FormState> formKey;
final String? dropdown1Value;
final String? textInput;
final String? error;
final String? dropdown2Value;
bool get isFinished => dropdown1Value != null && textInput != null && dropdown2Value != null;
MyFormState copyWith({
GlobalKey<FormState>? formKey,
String? dropdown1Value,
String? textInput,
String? error,
String? dropdown2Value,
}) {
return MyFormState(
formKey ?? this.formKey,
textInputController,
dropdown1Value ?? this.dropdown1Value,
textInput ?? this.textInput,
error ?? this.error,
dropdown2Value ?? this.dropdown2Value,
);
}
@override
List<Object?> get props => [formKey, textInputController, dropdown1Value, textInput, error, dropdown2Value];
}
sealed class MyFormAction {
const MyFormAction();
}
class Dropdown1ChangedAction extends MyFormAction {
const Dropdown1ChangedAction(this.value);
final String value;
}
class ValidateTextInputAction extends MyFormAction {
const ValidateTextInputAction();
}
class Dropdown2ChangedAction extends MyFormAction {
const Dropdown2ChangedAction(this.value);
final String value;
}
class ResetAction extends MyFormAction {
const ResetAction();
}
typedef MyFormStore = Store<MyFormState, MyFormAction>;
MyFormState reducer(MyFormState state, MyFormAction action) => switch ((state, action)) {
(_, Dropdown1ChangedAction(:final value)) => MyFormState(
state.dropdown1Value == null ? state.formKey : GlobalKey(),
state.textInputController..clear(),
value,
),
(MyFormState(textInput: null), ValidateTextInputAction()) => switch (validate(state.textInputController.text)) {
null => MyFormState(
state.formKey,
state.textInputController,
state.dropdown1Value,
state.textInputController.text,
),
final error => state.copyWith(error: error),
},
(MyFormState(:final textInput?, error: null, dropdown2Value: null), Dropdown2ChangedAction(:final value)) =>
state.copyWith(dropdown2Value: value),
(_, ResetAction()) => MyFormState(GlobalKey<FormState>(), state.textInputController..clear()),
(_, _) => throw Exception('Invalid state/action combination: $state, $action'),
};
String? validate(String? value) {
if (value == null || value.isEmpty) {
return 'Please enter some text';
} else if (value.length < 3) {
return 'Please enter at least 3 characters';
} else if (value.length > 10) {
return 'Please enter at most 10 characters';
} else {
return null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment