I am making a group buying app, which will show list of nearest deal, newest deal, and ending soon deal. If these 3 lists are empty, I want to show a button for user to add a deal. But I encountered "setState called during Build" error. Here is what I have tried:
int listCount = 0;
bool hasNearest = false;
bool hasNewest = false;
bool hasEnding = false;
bool showButton = false;
void checkState(int count, String mode) {
listCount = listCount count;
if (mode == 'nearest') hasNearest = true;
if (mode == 'newest') hasNewest = true;
if (mode == 'ending') hasEnding = true;
if (hasNearest && hasNewest && hasEnding && listCount <= 0) {
setState((){
showButton = true;
})
}
}
@override
Widget build(BuildContext context) {
return Column(
children: [
// for nearest deal
FutureBuilder(
future: getNearestDealMethod(), // method from other helper class, returning future object
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.done:
if (snapshot.hasData) {
List<Deal> list = snapshot.data;
checkState(list.length, 'nearest');
if (list.length > 0) { // show deal widget }
} else {
return Text("No Deal");
}
break;
default:
return Text("Error");
}
}
),
// for newest deal
FutureBuilder(
future: getNewestDealMethod(), // method from other helper class, returning future object
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.done:
if (snapshot.hasData) {
List<Deal> list = snapshot.data;
checkState(list.length, 'newest');
if (list.length > 0) { // show deal widget }
} else {
return Text("No Deal");
}
break;
default:
return Text("Error");
}
}
),
// for ending deal
FutureBuilder(
future: getEndingDealMethod(), // method from other helper class, returning future object
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.done:
if (snapshot.hasData) {
List<Deal> list = snapshot.data;
checkState(list.length, 'ending');
if (list.length > 0) { // show deal widget }
} else {
return Text("No Deal");
}
break;
default:
return Text("Error");
}
}
),
if (showButton) ...[
Text('show button here')
]
]
);
}
I'm not using a provider to store fetch data, because the client insisted that every time this page is load, app must retrieve the latest value from cloud.
What should I do to make this work? Or is my approach incorrect here? Any help is appreciated.
CodePudding user response:
In a future builder set state will rebuild the ui and call the future again. An option to fix this is to extract the widget to a new class and perform set state in the extracted widget.. or you can consider using some state management libraries like bloc or river pod
CodePudding user response:
Don't pass future function directly just pass the instance of future builder like
Future<List<....>>?futureFile ;
@override void initState() {
super.initState();
futureFile = getNearestDealMethod();
}
FutureBuilder(
future: futureFile, // method from other helper class, returning
futurobject
builder: (context, snapshot) {
switch (snapshot.connectionState) {
.....