Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

  • This article describes how to call a function when the Flutter stateless widget is started

Ever wonder how to call asynchronous functions from stateless widgets when a Flutter starts?

One of the most common scenarios in mobile development is calling asynchronous functions when a new view is displayed. In Flutter, this can be done using stateful widgets and calling your code in the initState function.

class Example extends StatefulWidget { Example({Key key}) : super(key: key); _ExampleState createState() => _ExampleState(); } class _ExampleState extends State<Example> { @override void initState() { _getThingsOnStartup().then((value){ print('Async done'); }); super.initState(); } @override Widget build(BuildContext context) { return Container(); } Future _getThingsOnStartup() async { await Future.delayed(Duration(seconds: 2)); }}Copy the code

What if you want to call it from the stateless widget? Well, that’s possible. Using the stateful widget as the root widget, you can also provide callback functions to perform startup logic. See the example below.

Create a StatefulWrapper that accepts a function to call and a child item to display.

/// Wrapper for stateful functionality to provide onInit calls in stateles widget
class StatefulWrapper extends StatefulWidget {
  final Function onInit;
  final Widget child;
​
  const StatefulWrapper({@required this.onInit, @required this.child});
​
  @override
  _StatefulWrapperState createState() => _StatefulWrapperState();
}
​
class _StatefulWrapperState extends State<StatefulWrapper> {
​
@override
  void initState() {
    if(widget.onInit != null) {
      widget.onInit();
    }
    super.initState();
  }
​
  @override
  Widget build(BuildContext context) {
    return widget.child;
  }
}
Copy the code

Wrap the UI of the Stateless widget in StatefulWrapper and pass the onInit logic you want to run

class StartupCaller extends StatelessWidget { @override Widget build(BuildContext context) { return StatefulWrapper( onInit: () { _getThingsOnStartup().then((value) { print('Async done'); }); }, child: Container(), ); } Future _getThingsOnStartup() async { await Future.delayed(Duration(seconds: 2)); }}Copy the code

That’s it. This function is called only once when the stateful widget is initialized.