[Solved] How to setState inside showModalBottomSheet

Question

Asked by Manvendra S on June 10, 2019 (source).

Is there any limitation in BottomSheet that we cannot update the widget states? As you can see in the example below I'm using a Switch but its display is not changing, although the value update, it's just that it doesn't get re-render again.

This is part of StatefulWidget right now.

This same problem I'm experiencing with the DropdownButton widget. These both work in normal page fine.

Does anybody have the idea?

showModalBottomSheet(
  context: context,
  builder: (BuildContext context) {
    return BottomSheet(
      onClosing: () {},
      builder: (BuildContext context) {
        return Switch(
          onChanged: (bool v) {
            debugPrint('v is ${v.toString()}');
            // b = v; <<-- This is also not working when using StatelessWidget
            setState(() => b = v);
            debugPrint(b.toString());
          },
          value: b,
        );
      },
    );
  },
);

Answer

Question answered by creativecreatorormaybenot (source).

The problem here is that the BottomSheet you are creating is not part of your StatefulWidget. If you only made your widget stateful for the purpose of using setState inside of showModalBottomSheet, you can revert that change now.

What you really want to do is set the state inside of your BottomSheet. You do that by either passing a StatefulWidget to the builder or by using a StatefulBuilder, which I will do for this example for the sake of simplicity:

showModalBottomSheet(
  context: context,
  builder: (BuildContext context) {
    return BottomSheet(
      onClosing: () {},
      builder: (BuildContext context) {
        bool b = false;
        return StatefulBuilder(
          builder: (BuildContext context, setState) => Switch(
            onChanged: (bool v) {
              setState(() => b = v);
            },
            value: b,
          ),
        );
      },
    );
  },
);

I also moved the b value inside the builder function of the BottomSheet.

If you want to use the value of b inside of your original StatefulWidget as well, you would move it out again and you probably want to call this.setState as well to also update the other widget (only if you need it to update).

DART FLUTTER
SHARE: