0

When a widget has some logic (ex: if/else), if often see the logic being done at the beginning of the build method and stored in variables that are reused.

For example

Widget build(BuildContext context) {
  // ... Some logic 0 here
  final result0 = // ...
  // ... Some logic 1 here
  final result1 = // ...
  // ...
  return Column(
    children: [
      // ...
      MyWidget0(
        parameter: result0,
      ),
      // ...
      MyWidget1(
        parameter: result1,
      ),
      // ...
    ],
  );
}

which I sometimes feel a bit hard to read as the logic of the widget x is at the beginning and not with the widget x itself.

I never see people using lambda methods like:

Widget build(BuildContext context) {
  return Column(
    children: [
      // ...
      MyWidget0(
        parameter: () {
          // ... Some logic 0 here
          final result0 = // ...
          return result0;
        }(),
      ),
      // ...
      MyWidget1(
        parameter: () {
          // ... Some logic 1 here
          final result1 = // ...
          return result1;
        }(),
      ),
      // ...
    ],
  );
}

This allows to have the logic x next to the widget x (where it is used).

And also, if MyWidget1 is not always built:

Column(
  children: [
    // ...
    if (condition) 
      MyWidget1(
        // ...
      ),
    // ...
  ],
),

logic 1 won't be executed if condition is false; unlike in the first example where logic 1 is always run at the beginning of the build method.


I was wondering if there were any drawbacks to using lambda functions in the build method as illustrated. Or if it is a bad practice, why?

Valentin Vignal
  • 6,151
  • 2
  • 33
  • 73

2 Answers2

1

There shouldn't be any difference. I'd expect the compiler to optimize the anonymous function usage so that both versions are equivalent. And indeed, using godbolt.org to examine the disassembled output, I don't see any difference between:

void main() {
  print('foo');
}

and

void main() {
  () { print('foo'); }();
}

Whether superfluous anonymous functions make build methods more readable is subjective. I personally think that they would usually make code (especially the surrounding code) less readable due to the extra indentation and the increased space between arguments.

jamesdlin
  • 81,374
  • 13
  • 159
  • 204
1

I don't think that using lambda functions in build is a bad practice. It is just a matter of personal preference. In the example that you used, the lambda function will work perfectly. Just for readability purposes, I don't use lambda functions.

I think this is more readable than using lambda:

class MyWidget extends StatelessWidget {
  final isLoggedIn = true;
  @override
  Widget build(BuildContext context) {
    final text = isLoggedIn ? 'Welcome' : 'Login';
    return Text(text);
  }
}

Using lambda

class MyWidget extends StatelessWidget {
  final isLoggedIn = true;
  @override
  Widget build(BuildContext context) {
    return Text(
      () {
        return isLoggedIn ? 'Welcome' : 'Login';
      } (),
    );
  }
}
Ravi Singh Lodhi
  • 2,605
  • 1
  • 9
  • 12