How to save data of FutureProvider to avoid rebuild

Viewed 162

I am using FutureProvider to fetch data(places) from Laravel API to show that data in flutter. Now the problem is it is rebuilding again and again that even server started throwing error of "too many attempts". I am using ListView.builder to show all places fetch from API but when I scroll to next places and then scroll back to previous it rebuilds. Mean FutureProvider is rebuilding again and again. Here is code attached. I also tried to add addAutomaticKeepAlives: true, in ListView to save the state

Container(
  height: 100,
  child: ListView.builder(
    addAutomaticKeepAlives: true,
    scrollDirection: Axis.horizontal,
    itemCount: places.length,
    itemBuilder: (_, index) {
      return FutureProvider(
        initialData: null,
        
        create: (context) =>
            getFireIceCount(index, places),
        child: Consumer<List<dynamic>>(
          builder: (context, fireIceCount,
              child) {
            return (fireIceCount != null)
                ? (fireIceCount.isNotEmpty)
                    ? PlacesImageViewer()
                    : Center(
                        child:
                            CircularProgressIndicator(
                          color:
                              Colors.cyan,
                        ),
                      )
                : Center(
                    child:
                        CircularProgressIndicator(
                      color: Colors.red,
                    ),
                  );
          },
        ),
      );
    },
  ),
),
1 Answers

You would need a stateful widget, because the State object associated with it is maintained between rebuilds. The first advice would be to extract the widget you are building out of the listview itself

class SampleItem extends StatefulWidget {
  const SampleItem({Key? key}) : super(key: key);

  @override
  _SampleItemState createState() => _SampleItemState();
}

class _SampleItemState extends State<SampleItem> {
  late final Future<List<dynamic>> items=getFireIceCount(index, places);

  @override
  Widget build(BuildContext context) {
    return BuildYOurItemHere();
  }
}

But the most important thing would be actually making less requests to the backend, fetch a range of items instead of one by one, and try to implement pagination both in your app and the server. This single handedly will decrease the times you hit the server, increase the performance as you are making less requests.

Related