how to update build method in flutter without causing memory leak
You have no need to set state. The FutureBuilder
already rebuilds it's build
method when the future finishes. You can just put this FutureBuilder
around anything you want to update and use the snapshot.data
to process.
Just as a bonus tip: FutureBuilders
have a initialData
parameter so you can use that and be sure that you never receive null
values for example!
Edit:
Here is an example of how to do something like what you want to achieve using Bloc's Cubit base class. You could do something like this and create this cubit variable up in your widget tree and then pass it down wherever you want. Wherever you use this NewWidget
and pass the same variable instance they will all update together.
final cubit = DocGetter(
() {
return FirebaseFirestore.instance.collection('users').doc('userId').get()
},
);
cubit.futureUpdate(
FirebaseFirestore.instance.collection('users').doc('userId').get(),
);
cubit.futureUpdateFunction(
FirebaseFirestore.instance.collection('users').doc('userId').get,
);
class NewWidget extends StatelessWidget {
const NewWidget({
Key? key,
required this.child,
required this.getter,
this.childWhileEmpty,
}) : super(key: key);
final Widget child;
final Widget? childWhileEmpty;
final DocGetter getter;
@override
Widget build(BuildContext context) {
return StreamBuilder<Map>(
initialData: cubit.state,
stream: cubit.stream,
builder: (context, snapshot) {
final map = snapshot.data!;
if (map.isEmpty) {
return childWhileEmpty ?? const SizedBox.shrink();
} else {
return child;
}
},
);
}
}
class DocGetter extends Cubit<Map> {
DocGetter(Future<Map> Function() fn, {Map? initialState})
: super(initialState ?? {}) {
fn().then(update);
}
Future<void> futureUpdateFunction(Future<Map> Function() fn) async {
final map = await fn();
emit(map);
}
Future<void> futureUpdate(Future<Map> futureMap) async {
final map = await futureMap;
emit(map);
}
void update(Map newMap) => emit(newMap);
}
Nadia Yaseen
Updated on January 03, 2023Comments
-
Nadia Yaseen over 1 year
I have this code which fetch data from
Firestore
and I havesetState
during build, but it keeps giving warnings about memory leak, however it's updated, but I need a way that avoid this warning, here is simple samplebool isOne = false ; //Stfl Widget Widget build(BuildContext context) { return Stack( //edit children [ !isOne? Text('bool varible is false') : Text('bool varible is true') FutureBuilder( future: FirebaseFirestore.instance.collection('users') .doc('userId').get(), builder: (context, AsyncSnapshot snapshot) { if(!snapshot.hasData){ return Text(''); }else{ if(mounted) { setState(() { isOne = true ; // memory leak warning }); } } return snapshot.data['name'];
also I tested this but the same warning
WidgetsBinding.instance!.addPostFrameCallback((_) => setState(() {}));
How can I handle that type of simple update during build tree without any memory leak causing?
-
Nadia Yaseen about 2 yearsJosteve i just read your link but i need example similar for mine above sing management package , and thanks if you did it in answer to vote it
-
-
Yeasin Sheikh about 2 yearsCan you try with checking
FutureBuilder
's snapshot state like waiting and errors? -
Josteve about 2 yearsYou should use a state management package instead of calling setState repeatedly...See Riverpod here: riverpod.dev
-
Nadia Yaseen about 2 yearssorry it was my bad , please see my question again since i edit it , it is out Future widget
-
Felipe Morschel about 2 yearsI can see that, but you only need to swap the Stack and the FutureBuilder, put the Stack inside and process it all inside the FutureBuilder
-
Nadia Yaseen about 2 yearsof course i can do it , but it is just similar simple for big other code that cannot do this way
-
Felipe Morschel about 2 yearsMy suggestion then would be for you to look for other state management approaches. Something like Bloc or anything else where you can update a simple part of your code only and from far away in your widget tree. Would you like some better explanation into how to use Bloc (or Cubits that are simpler)? I could edit the comment to add that.
-
Nadia Yaseen about 2 yearsyes sure thanks
-
Felipe Morschel about 2 yearsUpdated the comment