Flutter Best Practices — Part 2

By | October 17, 2022

1. Avoid Functional Widgets

We usually have a situation where we need to separate out UI code from the widget, But we avoid creating a separate widget and use function which returns Widget. This practice have some benefits, like you don’t need to pass all parameters in your new widget, You have less code and less files. But this approach may cause issue when you want to inspect your widget. Let’s see this in depth.

When you use functional widget code looks like this.

Widget functionWidget({ Widget child}) {
return Container(child: child);
}

You can now use it as

functionWidget(
child: functionWidget(),
);

In this case Widget tree will look something like this

Container
Container

Instead if we use Widget, Our widget looks like

class ClassWidget extends StatelessWidget {
final Widget child;

const ClassWidget({Key key, this.child}) : super(key: key);

@override
Widget build(BuildContext context) {
return Container(
child: child,
);
}
}

You can use it as

ClassWidget(
child: ClassWidget(),
);

And in this case Widget tree looks like this

ClassWidget
Container
ClassWidget
Container

Advantages:

  • By using functions to split your widget tree into multiple widgets, you expose yourself to bugs and miss on some performance optimizations.
  • There is no guarantee that you will have bugs by using functions, but by using classes, you are guaranteed to not face these issues.
    Follow this link to find out more.

2. Specify Types for variables

Don’t

var count = 10;
final person = Person();
const timeOut = 6000;

Do

final int count = 10;
final Person person = Person();
final String name = 'John Doe';
const int timeOut = 6000;

This may be a personal choice as dart gives you the power to not specify type when it is assigned or when inside functions/classes. You may/may not want to use this based on your personal preference. The compiler may give you a warning if you are assigning a variable type which is directly assigned inside a class/function. In those cases, you can remove the types, but it is good to keep types when the variables are global.

3. Use ‘is’ instead of ‘as’

Don’t

(item as Person).name = 'John Doe';

Do

if (item is Person)
item.name = 'John Doe';

4. Use Item Extent in List if you have longer lists

ItemExtent will drastically improve the performance if you want to jump to a specific index on a button click or something.

Advantage: Specifying an itemExtent is more efficient than letting the children determine their extent because scrolling already knows children’s extent to save time and energy.

class MyListView extends StatelessWidget {
  final _scrollController = ScrollController();
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(onPressed: () {
        _scrollController.jumpTo(
          _scrollController.position.maxScrollExtent,
        );
      }),
      body: ListView(
        controller: _scrollController,
        children: List.generate(10000, (index) => Text('Index: $index')),
        itemExtent: 600,
      ),
    );
  }
}

Use ?? and ?. operators

// Don't
bool isValid =  done == null ? false : true;// Do
bool isValid = done ?? false;// Don't
bool isValid = done == null ? null : a.b;

// Do
bool isValid = a?.b;

Thanks for reading…

More coming…

Stay tuned and become a pro in Flutter…

Please share your valuable comments below.

More tutorials

Video Tutorials

Leave a Reply

Your email address will not be published. Required fields are marked *