Is it normal a stateful widget is called at each frame?

157 views Asked by At

While debugging my stateful widget that reset its state, I was surprised to see it is called at each frame (I mean initState() and build() are called many times).

I guess this is not OK and would like to get advice about it and therefore what to look at.

The tree context:


class _SmartboxDashboard extends State<SmartboxDashboard>
    with
        Module<SmartboxDashboard>,
        SingleTickerProviderStateMixin, //, TickerProviderStateMixin
        AutomaticKeepAliveClientMixin<SmartboxDashboard> {
  @override
  bool get wantKeepAlive => true;

  // blah blah

  @override
  Widget build(BuildContext context) {
    super.build(
        context);
  return Consumer<StateModel>(builder: (context, appState, child) {
      return DefaultTabController(
        length: _tabSectionBodies.length,
        child: Scaffold(
          
          resizeToAvoidBottomInset: true,
          appBar: AppBar(

          // == The drawer
          endDrawer: Drawer(
            key: _drawerKey,
           
            child: ListView(
              // Important: Remove any padding from the ListView.
              padding: EdgeInsets.zero,
              children: [
                const DrawerHeader(
                  decoration: BoxDecoration(
                    color: Colors.blue,
                  ),
                  child: Text('Drawer Header'),
                ),


                // == BMS settings update enabler
              BmsSettingsUpdateMode(appState.isBmsSettingsUpdateEnabled),


               // blah blah

My widget code is as follows:


/// Expert mode selector
class BmsSettingsUpdateMode extends StatefulWidget {
  final bool isBmsSettingsUpdateEnabled;
  BmsSettingsUpdateMode(this.isBmsSettingsUpdateEnabled);
  @override
  _BmsSettingsUpdateMode createState() => _BmsSettingsUpdateMode();
}

class _BmsSettingsUpdateMode extends State<BmsSettingsUpdateMode> {
  bool isBmsSettingsUpdateEnabled = false;

  @override
  void initState() {
    super.initState();
    isBmsSettingsUpdateEnabled = widget.isBmsSettingsUpdateEnabled;
  }

  @override
  Widget build(BuildContext context) {
    /// BMS settings update enabler
    //if (!isBmsSettingsUpdateEnabled) return Text("Not expert mode");

    return Consumer<StateModel>(builder: (context, appState, child) {
      return ListTile(
          leading: Switch(
              value: isBmsSettingsUpdateEnabled,
              onChanged: (value) async {
                if (value) {
                  final r = await openPasswordForm(
                      formTitle: "BMS settings update",
                      inputHintText: "A password is required",
                      context: context,
                      callback: (context, password) {
                        // Cancel or no password provided, simply close
                        if (password == null) return false;

                        if (password == "1707") {
                          snackBar(context,
                              "OK, you can edit the BMS settings from within the BMS bottom tab");

                          return true;
                        }

                        // Wrong password
                        snackBar(context, 'Wrong password "$password"');

                        return false;
                      });

                  if (r == true)
                    setState(() {
                      isBmsSettingsUpdateEnabled =
                          appState.isBmsSettingsUpdateEnabled = true;
                    });
                } else {
                  setState(() {
                    isBmsSettingsUpdateEnabled =
                        appState.isBmsSettingsUpdateEnabled = false;
                  });
                }
              }),
          title: Text(isBmsSettingsUpdateEnabled
              ? "BMS settings: enable update"
              : "BMS settings: read only"),
          subtitle: Text(isBmsSettingsUpdateEnabled
              ? "Turning to \"read only\" will prevent you from updating the BMS settings, which is the default"
              : "Turning to \"enable update\" will show more screens and deeper information about your batteries"));
    });
  }
}

0

There are 0 answers