0

I am confused between these three ways of passing/building widgets:

1.

  Widget _myDisplay() {
    return [widgets showing content];
  }

  @override
  Widget build(BuildContext context) {
    return _myDisplay();
  }
  @override
  Widget build(BuildContext context) {
    return MyDisplay();
  }

where MyDisplay is defined as such (I'm not sure if it's crucial whether MyDisplay is a StatelessWidget or a StatefulWidget):

class MyDisplay extends StatelessWidget {
  const MyDisplay({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return [widgets showing content];
  }
}
  Widget _myDisplay = [widgets showing content];

  @override
  Widget build(BuildContext context) {
    return _myDisplay;
  }

I've read this thread comparing the first two methods, and from what I understand, using a unique, named class extending StatelessWidget or StatefulWidget allows you to use the const keyword which signifies that it will not be rebuilt when the Widget tree is rebuilt.

However, what about the 3rd method above? Is it the same as 1. or 2., or completely different? If so, how is it different and when is it preferred?

Thanks!

Nathan Tew
  • 432
  • 1
  • 5
  • 21
  • Also see [What is the difference between functions and classes to create reusable widgets?](https://stackoverflow.com/q/53234825/) – jamesdlin Jul 16 '22 at 18:22

1 Answers1

0
  • Type 1: helper methods
  • Type 2: Widgets
  • Type 3: Variables

For type 1 and 2, I will highly recommend to check Widgets vs helper methods | Decoding Flutter

Helper methods will rebuild everything on every state changes which can be heavy based on scenario like using animated-widgets.

Try using Widget with const constructor to get better performance,

Now for the 3rd type variable. It is totally different from helper method and widgets. This variable won't change until you handle the variable state. Test this example code, and you will find the issue where data doesn't change on type3(variable) case.

class Test3 extends StatefulWidget {
  const Test3({Key? key}) : super(key: key);

  @override
  State<Test3> createState() => _Test3State();
}

class _Test3State extends State<Test3> {
  String data = "A";
  late Widget _myDisplay = Text("$data");
  Widget _myDisplayMethod() => Text("$data");

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(onPressed: () {
        setState(() {
          data = "b";
        });
      }),
      body: Center(
        child: Column(
          children: [
            _myDisplay, //variables doesn't update state(based on cases)
            _myDisplayMethod(),
          ],
        ),
      ),
    );
  }
}
Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
  • can I say then that using variables is better if I intentionally want the displayed widgets to not be updated? – Nathan Tew Jul 16 '22 at 15:37
  • think so, on if it is independent , more like final – Md. Yeasin Sheikh Jul 16 '22 at 16:11
  • 1
    It breaks the context chain, which means you're violating the build system's contract. If it works, it's accidental, and have fun debugging if it doesn't work. The framework already works very hard to not rebuild widgets. It's very unlikely that you can do a better job by hand. – Randal Schwartz Jul 17 '22 at 01:33
  • 1
    @RandalSchwartz hm so you’d actually recommend that I avoid using variables to hold widgets? – Nathan Tew Jul 17 '22 at 23:52
  • 1
    Correct. Widgets should arise only during the build() chain. – Randal Schwartz Jul 18 '22 at 00:16
  • @RandalSchwartz hmm… how about lists of widgets, like used in columns or rows? If I want a dynamically changing list, I inevitably have to update the list in some method outside of the build() chain right? How does that compare to using a Widget stored in a variable? – Nathan Tew Jul 22 '22 at 15:51
  • you update the List of data that the widgets depend on. – Randal Schwartz Jul 22 '22 at 22:45