What is Form in Flutter?
Form is a widget that acts as a container for grouping and validating multiple form fields (like TextFormField, DropdownButtonFormField, etc.). It provides a way to save, reset, or validate all the fields at once using a GlobalKey<FormState>. Forms are essential for handling user input in a structured and maintainable way.
Basic Usage
To create a form, wrap your input fields in a Form widget and give it a GlobalKey<FormState>. Each input field should be a TextFormField (or similar) with validator and optionally onSaved functions.
Key Components
- Form – The container widget that holds the form fields and manages their state.
- GlobalKey<FormState> – A unique identifier that allows you to access the form's state (validate, save, reset).
- TextFormField – A Material Design text input field that integrates with Form. It provides
validatorandonSavedcallbacks. - validator – A function that returns an error string if the input is invalid, or
nullif valid. - onSaved – A function that is called when
_formKey.currentState!.save()is invoked, typically to store the field value. - autovalidateMode – Determines when validation runs (e.g.,
AutovalidateMode.onUserInteraction).
Validating Form Fields
The validator function is called when _formKey.currentState!.validate() is executed. It should return an error string if the input is invalid, or null if it's valid. The error string is displayed below the field.
Saving Form Data
Use the onSaved callback to store the field value when _formKey.currentState!.save() is called. You typically do this after validation passes.
Resetting the Form
To clear all fields and reset validation errors, call _formKey.currentState!.reset().
Using Controllers for Fine Control
If you need to programmatically change the text or listen to changes, use a TextEditingController for each field. Remember to dispose them in State.dispose().
Common Mistakes Beginners Make
- Not using a GlobalKey: Without a key, you cannot access the form state to validate or save.
- Forgetting to wrap fields with Form:
TextFormFieldonly works properly inside aFormwidget. - Not handling null in validator: Always check for null because the value can be null, especially if the field is empty.
- Calling
save()beforevalidate(): Always validate first; otherwise you might save invalid data. - Using
onChangedfor validation instead ofvalidator: Thevalidatoris integrated with the form's validation system and automatically shows errors. - Not disposing controllers: If you use
TextEditingController, dispose them to avoid memory leaks. - Setting
autovalidateModeto always: Can be annoying for users; useonUserInteractionfor a better experience.
Key Points to Remember
- Wrap your input fields with a
Formand provide aGlobalKey<FormState>. - Use
TextFormFieldfor text input; it has built‑in form integration. - Define
validatorto check input and return an error string when invalid. - Call
_formKey.currentState!.validate()to trigger validation. - After successful validation, call
_formKey.currentState!.save()to populate your variables viaonSaved. - Use
TextEditingControllerif you need to control or listen to the text. - Always dispose controllers in
State.dispose().
Common Interview Questions
- How does Form widget manage its children's state?
- What is the role of
GlobalKey<FormState>in a form? - Explain the difference between
validatorandonSaved. - How would you implement password confirmation validation?
- What is
autovalidateModeand when would you use it? - How do you programmatically set the focus to a specific form field?
- How can you handle asynchronous validation (e.g., checking if a username is already taken)?
- What happens if you don't provide a
validatorfor a field? Can it still be validated?