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

3,669

Solution 1

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.

Solution 2

If you have a data source which constantly updates itself, you can use a StreamBuilder instead of FutureBuilder. StreamBuilder listens to the data source and rebuilds the widget after every update it gets from it.

Solution 3

Recently I also faced this problem, where I was passing data from another class with setState. The data was updated initially using initState then I was changing that particular data using a local variable, but when new data arrived from the parent class this was not updating.

later I found didUpdateWidget method

@override
  void didUpdateWidget(covariant ExampleClass oldWidget) {
    print("didUpdateWidget: ${widget.value}");
    selectedIndex = widget.value.toInt().toString(); //local variable
    list.clear(); // list with data
    _buildList(); // list will rebuild with new data
    super.didUpdateWidget(oldWidget);
  }

basically using this override method in the stateful class we can do something whenever there is a change in the widget.
Now I can update the data using local and parent variables.

Share:
3,669
CAoT
Author by

CAoT

Updated on December 21, 2022

Comments

  • CAoT
    CAoT over 1 year

    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();
                }
              }),
        );
      }
    }
    
  • CAoT
    CAoT almost 4 years
    Thanks for the help! It almost works! Every time when the stream updates it brings the widget to update itself - but with the same data. So my snapshot.data has different data that i pass in, but inside the widget the data remain the same. I watch the data in didUpdateWidget to see if they are the same, and they are. I tried to create the widget with new in the parent widget, but it's not working.. Any suggestion?