Search code examples
flutterdartwebsocketreloadsetstate

Flutter: How to receive new Data and update Widget without rebuildung


I'm currently facing an annoying I think design problem made by myself and flutter :D

In my widgets I work with FutureBuilder. When the Widget gets created, it fetches initial the data - everything's fine. Now I got a WebSocket connection which sends me updated data. I pass this data to my widget and now I am facing the problem that either I change the data and the Widget does not reload or I additionally use setState and the widget will update itself and again fetches new data because it's rebuild and futurebuilder comes into play again. That's not efficient at all. How can I prevent this behavior.

I think about, that my Structure is maybe not right for this flutter behavior and therefore I maybe have to load the data initially outside the widget, pass em in via constructor and set a listener inside my Widget for the WebSocket notification and then call setState... right?

Here an short example that does rebuild and therefore again fetches data by itself -> so not my desired solution:

class _ExampleState extends State<Example> {

  Stream wsData;

  _ExampleState() {
    wsData.listen((event) {
      setState(() {
        //update data
      });
    });
  }

  _getData() {
    // Call network manager and fetch data
    return {'fetchedData': 'data'};
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: FutureBuilder(
          future: _getData(),
          builder: (BuildContext context, AsyncSnapshot snapshot) {
            if (snapshot.data != null) {
              Text('data arrived: ' + snapshot.data.toString());
            } else {
              return CircularProgressIndicator();
            }
          }),
    );
  }
}

Solution

  • My solution: In my use case it just wouldn't work with Streambuilder. The data that were passed into the Widget after new data came from the stream were the same somehow.. Now I am using FutureBuilder to fetch the data initial and pass a Stream to my Widget. The Widget listens to changes on the Stream and updates itself..

    Also, like mentioned from @Rémi Rousselet, I start the fetch process in the initState method and assign it to a local future variable, instead of triggering the fetch directly with FutureBuilder.