close

Flutter build called multiple times

This is the difficult that each Flutter designer will confront while doing improvement.

Why FutureBuilder Called once more?

This is because of state changes that come if setState() called, which triggers manufacture() technique, and because of this inside gadgets will be re-introduce once more. Anyway, how we can stop it?

Note: The issue isn’t FutureBuilder called on numerous occasions, the issue is Future item setting off occasion over and over. The above inquiry just sums up everything inside FutureBuilder.

First Approach:

In the primary methodology, we can stop the re-setting off of gadgets by proclaiming Future item inside initState() technique, which called just ones in the stateful gadget lifecycle. It illuminated the issue of calling _fetchData() technique which called on different occasions.

class FutureSample extends StatefulWidget {
  // Create instance variable
  @override
  _FutureSampleState createState() => _FutureSampleState();
}

class _FutureSampleState extends State<FutureSample> {
  Future myFuture;

  Future<String> _fetchData() async {
    await Future.delayed(Duration(seconds: 10));
    return 'DATA';
  }

  @override
  void initState() {
    // assign this variable your Future
    myFuture = _fetchData();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: FutureBuilder(
          future: myFuture,
          builder: (ctx, snapshot) {
            if (snapshot.hasData) {
             return Text(snapshot.data.toString());
            }
            return CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}

Second Approach:

Dart async bundle have class AsyncMemoizer which settle this issue inside by utilizing the strategy runOnce. The inward code inside this strategy will run precisely ones.

class MemoizerSample extends StatefulWidget {
  @override
  _MemoizerSampleState createState() => _MemoizerSampleState();
}

class _MemoizerSampleState extends State<MemoizerSample> {
  AsyncMemoizer _memoizer;

  _fetchData() async {
    return this._memoizer.runOnce(() async { // This below code will call only ones. This will return the same data directly without performing any Future task.
      await Future.delayed(Duration(seconds: 10));
      return 'DATA';
    });
  }

  @override
  void initState() {
    super.initState();
    _memoizer = AsyncMemoizer();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: FutureBuilder(
          future: _fetchData(),
          builder: (ctx, snapshot) {
            if (snapshot.hasData) {
              return Text(snapshot.data.toString());
            }
            return CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}

Thank you

Summery

It’s all About this issue. Hope all solution helped you a lot. Comment below Your thoughts and your queries. Also, Comment below which solution worked for you? Thank You.

Also Read

Leave a Comment