I use riverpod for state management in flutter development.
I'm now trying to create a common component that needs state management.
I use riverpod to make a common component with like the following code.
class InputTextareaModel with ChangeNotifier {
String text;
String error;
String Function(String text) _validator;
void Function(String text) _onChanged;
bool _autoValidation;
set validator(String Function(String text) validator) {
this._validator = validator ?? (String text) => null;
}
set onChanged(void Function(String text) onChanged) {
this._onChanged = onChanged ?? (String text) {};
}
set autoValidation(bool autoValidation) {
this._autoValidation = autoValidation ?? true;
}
InputTextareaModel() {
this.text = '';
this.error = null;
}
onChangedText(String value) {
this.text = value;
this._onChanged(value);
if (this._autoValidation) {
this.onValidation();
}
notifyListeners();
}
onValidation() {
this.error = this._validator(this.text);
notifyListeners();
}
bool isError() {
return this.error != null ? true : false;
}
}
class InputTextarea extends HookWidget {
final String label;
final int minLines;
final int maxLines;
final String placeholder;
final provider;
final String Function(String text) validator;
final void Function(String text) onChanged;
final bool autoValidation;
InputTextarea(
{Key key,
this.label,
this.placeholder,
provider,
this.validator,
this.onChanged,
this.autoValidation,
this.minLines = 3,
this.maxLines = 5})
: this.provider =
provider ?? ChangeNotifierProvider((_) => InputTextareaModel()),
super(key: key);
@override
Widget build(BuildContext context) {
final inputTextareaModel = useProvider<InputTextareaModel>(provider);
inputTextareaModel.validator = this.validator;
inputTextareaModel.onChanged = this.onChanged;
inputTextareaModel.autoValidation = this.autoValidation;
return TextField(
decoration: InputDecoration(
alignLabelWithHint: true,
labelText: this.label,
hintText: this.placeholder,
errorText: inputTextareaModel.error,
border: OutlineInputBorder(),
),
keyboardType: TextInputType.multiline,
minLines: this.minLines,
maxLines: this.maxLines,
onChanged: (value) {
inputTextareaModel.onChangedText(value);
},
);
}
}
And I'm calling this common component with code like this:
final messageProvider =
ChangeNotifierProvider.autoDispose((_) => InputTextareaModel());
InputTextarea(
minLines: 5,
label: "message",
placeholder: "test",
provider: messageProvider, // We are injecting the provider at here.
validator: (value) {
if (value.replaceAll("\n", "").isEmpty) {
return 'required message!';
}
return null;
},
),
I can create a common component this way too, but I'm not quite happy with it.
I feel that there is a better way to create common components using riverpod.
Or is it better to create it using statefulWidget etc. without using riverpod?
If you know any good way, please let me know!
Thank you.