0

I have a screen with a form that displays a drop-down list of counties. When the screen initially loads I want to set the default to the current country.

class _SignInScreenState extends State<SignInScreen> {
  final formKey = new GlobalKey<FormState>();

  String countryCode = _CountryCode();

  _countryCode() {
    Locale myLocale = Localizations.localeOf(context);
    return myLocale.countryCode;
  }

  @override
  Widget build(BuildContext context) {...

This results in the following error: "Only static members can be accessed in initializers". I researched this and it stated the solution was to initialise variables in initState(), as shown below:

  @override
  initState() {
    super.initState();
    countryCode = _countryCode();
  }

This does not produce an error however in the widget tree the value of countryCode is null whereas in the widget tree _countryCode() displays "US" correctly.

If I set the value of countryCode in init states does this not mean it will be reset every time the widget tree is redrawn?

Dercni
  • 1,216
  • 3
  • 18
  • 38
  • "Declare the variable in the build method." See https://stackoverflow.com/a/56676356/6704033 – Er1 Jun 03 '20 at 10:21
  • Worked perfectly. Learning here. So if I can declare vars in the initialiser and the build method, what's the difference? – Dercni Jun 03 '20 at 10:49
  • Initializing in `initState` is for setting up variables the first time. Localizations might change and therefore you want to rebuild your widget using the new Localization which is accessed using `BuildContext` – Er1 Jun 03 '20 at 12:15

1 Answers1

0

The main purpose of initState is for initializing variables and it'll only be called when the widget gets destroyed, so as long as dispose method of the widget is not called your variable which was initialized through initState would be alive and you can use it in build method.

Regarding build method, so whenever you change something in widget Flutter will call build method and rerender the widget through it's returned content and it has nothing to do with initState., this is essentially called 'Hot Reload'. Hope this resolves your query.

More info here: https://api.flutter.dev/flutter/widgets/State-class.html

Change your code to :

class _SignInScreenState extends State<SignInScreen> {
  final formKey = new GlobalKey<FormState>();

  String countryCode;

  @override
  initState() {
    Locale myLocale = Localizations.localeOf(context);
    countryCode = myLocale.countryCode;
  }

  // use variable here...
  @override
  Widget build(BuildContext context) {...
Jay Dangar
  • 3,271
  • 1
  • 16
  • 35
  • Your `initState(BuildContext context)` is not the override of `initState` from the `State` class correct? – Er1 Jun 03 '20 at 12:10
  • No it's. sorry didn't wrote that. If you need example regarding initialization you can checkout this code, I wrote to initialize inputController for InputField,which uses hintText as a variable. https://github.com/jaydangar/CookingApp/blob/master/lib/widgets/textfield_blocbuilder.dart – Jay Dangar Jun 03 '20 at 12:17
  • But `initState` doesn't have a BuildContext argument – Er1 Jun 03 '20 at 12:32
  • you can still access the context in initState. it's essentially the context passed from parent through various statemanagement techniques. see one of the state management technique used here : https://github.com/jaydangar/CookingApp/blob/master/lib/pages/login.dart – Jay Dangar Jun 03 '20 at 12:37
  • @Er1, this is another example I just created : https://dartpad.dev/flutter – Jay Dangar Jun 03 '20 at 13:02
  • I get what you're trying to say, but that doesn't apply to the question Dercni asked. The member variable context can be accessed during initState but can't be used for everything. As stated here https://stackoverflow.com/a/49458289/6704033 – Er1 Jun 03 '20 at 13:13