Skip to content

KYC registration steps: GlobalKey held as a field on a StatelessWidget #527

@TaprootFreak

Description

@TaprootFreak

Severity

High — Flutter anti-pattern causing form-state loss and redundant network work.

Problem

KycRegistrationPersonalStep and KycRegistrationAddressStep are StatelessWidgets that hold a GlobalKey<FormState> as an instance field:

  • lib/screens/kyc/steps/registration/steps/kyc_registration_personal_step.dart:32
  • lib/screens/kyc/steps/registration/steps/kyc_registration_address_step.dart:25

_buildStep (kyc_registration_page.dart) is called inside PageView(children: KycRegistrationStep.values.map(_buildStep).toList()), which runs on every rebuild of _KycRegistrationViewState — including every BlocBuilder<KycRegistrationSubmitCubit> / BlocBuilder<KycRegistrationStepCubit> state change. Each rebuild constructs fresh step widgets with fresh GlobalKeys.

Effect

A GlobalKey is bound to exactly one element. When the step widget is rebuilt with a new key, Flutter treats it as a different widget and rebuilds the Form element and its State from scratch:

  • the FormState / validation state is lost;
  • the CountryField's FutureBuilder state is recreated → initState re-runs → the country list is re-fetched.

(TextEditingControllers survive because they live in the persistent _KycRegistrationViewState; the form/validation state and the CountryField state do not.)

Suggested fix

Convert the two step widgets to StatefulWidget and hold the GlobalKey in their State — as KycNationalityView and SettingsEditAddressView already do correctly.

Context

Found during a deep audit of the KYC country/nationality data path (see #519).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions