为什么setState触发2 FutureBuilder运行?

问题描述

我正在使用FutureBuilder数据库调用中构建将来的项目列表。 由于某种原因,当我打电话给setState()时,FutureBuilder运行两次,这是有问题的。 我已经对代码进行了简化以说明问题:

void initState() {
  super.initState();
  futureIng = db.getIngredients();
}

Widget build(BuildContext context) {
  return Column(
    children: [
      getButton(),getDeleteButton(),FutureBuilder<List<Ingredientsql>>(
        future: futureIng,builder: (BuildContext context,AsyncSnapshot<List<Ingredientsql>> snapshot) {
          if (snapshot.hasData && snapshot.data != null) {
            if (snapshot.data.isEmpty) {
              return Text("nothing yet",style: TextStyle(color: Colors.white));
            }
            return Text(getList(snapshot.data));
          } else {
            return CircularProgressIndicator();
          }
        },),],);
}
}

void insertIngredient() {
Future<bool> success = db.insertIngredient("banana2"));
success.then((success) {
  if (success) {
    setState(() {
      futureIng = db.getIngredients();
    });
});


}

void deleteIngredient() {
var future = db.deleteIngredient("banana2");
future.then((value) {
  futureIng = db.getIngredients();
  futureIng.then((value) {
    setState(() {
      print("asd");
    });
  });
});


}

按下getButton()调用insertIngredient(),然后按下getDeleteButton()调用deleteIngredient()

因此,首先我插入“ banana2”成分,然后按Delete键将其删除。如您在deleteIngredient()函数中所见,该项目已被删除,然后我更新了以后的版本并调用setState()来重建输出文本。但是,FutureBuilder现在被调用了2次,一次什么也没发生(香蕉2仍在输出),然后立即再次被删除

这是怎么回事?

解决方法

我认为它是这样的: 首次将futurebuilder重建为其值已更改的窗口小部件,因此setState()方法使其进行重建。 第二次,是因为FutureBuilder重建了自己,因为您从AsyncSnapshot futureIng获得了值,并且这是您期望的“正常”重建。

因此,您不希望拥有的构建是由以下事实引起的:FutureIng的实例已更改,并且窗口小部件FutureBuilder像普通窗口小部件那样进行重建。

,

我仍然不确定100%为什么要运行两次,但是第一次“不正确”运行,connectionstate正在等待,第二次“正确”运行是“完成”。所以我用一个简单的if语句解决了我的问题。