Run async operation on widget creation

I often see people trying to execute an asyncronous operation in the render method of a widget. This doesn't work, but is also bad because it gets called every time the state or properties get updated. It can lead to a lot of unneccessary work. A StatefulWidget needs to be used to do this properly.

main.dart
class MyWidget extends StatefulWidget {
    
    State createState() => new MyWidgetState();
}

class MyWidgetState extends State<MyWidget> {
    var _result;

    
    void initState() {
        // This is the proper place to make the async calls        // This way they only get called once                // During development, if you change this code,        // you will need to do a full restart instead of just a hot reload                // You can't use async/await here, because        // We can't mark this method as async because of the @override        // You could also make and call an async method that does the following        loadAsyncData().then((result) {            // If we need to rebuild the widget with the resulting data,            // make sure to use `setState`            setState(() {                _result = result;            });        });    }
    
    
    Widget build(BuildContext context) {
        if (_result == null) {            // This is what we show while we're loading
            return new Container();
        }
        
        // Do something with the `_result`s here
        return new ResultWidget(_result);    }
}

In summary,

  1. Use a StatefulWidget
  2. Make the asyncronous call inside initState
  3. Make sure to call setState with the result, if we need to rerender
  4. Do something meaningful with the results :)
Brian Armstrong

Brian Armstrong

I'm Brian Armstrong, a SaaS developer with 15+ years programming experience. I am a Flutter evangelist and React.js enthusiast.