在Flutter的FutureBuilder中发生了无意义的API请求。

huangapple go评论101阅读模式
英文:

pointless Api requests occuring in future builder flutter

问题

我在我的Flutter应用程序中有一个Future Builder,它显示以下内容:

  1. 错误:如果在JSON解析中出现错误
  2. 数据:如果一切顺利
  3. 加载器:如果需要一些时间

一切都正常。Future调用了一个名为'future'的函数,该函数执行了一个获取学生数据的请求,并且'builder'将其显示出来。我在同一页上还有一个编辑对话框。我可以通过put请求编辑学生信息。问题是,当我点击编辑对话框中的表单字段时,我注意到get请求自动发生了大约10次。当我保存编辑时,会出现一个确认对话框,显示数据已更新。在此期间,再次发生get请求,最多达到10次。然后它弹出。因此,服务器上大约有20个无用的请求发生。
我认为这是因为当我点击表单字段时,键盘出现并且底层显示的小部件重建,调用API。当数据被编辑时,键盘回到原位,小部件重建,调用API。我该如何解决这个问题?

如果有帮助,这是代码:

child: FutureBuilder(
  future: APIs().getStudentDetails(),
  builder: (context, data) {
    if (data.hasError) {
      return Padding(
        padding: const EdgeInsets.all(8),
        child: Center(child: Text("${data.error}")),
      );
    } else if (data.hasData) {
      var studentData = data.data as List<StudentDetails>;
      return Padding(
        padding: const EdgeInsets.fromLTRB(0, 15, 0, 0),
        child: SingleChildScrollView(
          child: SizedBox(
            height: MediaQuery.of(context).size.height * 0.9,
            child: ListView.builder(
              itemCount: studentData.length,
              itemBuilder: ((context, index) {
                final student = studentData[index];
                final id = student.studentId;
                final father = student.fatherName;
                final mother = student.motherName;
                final cg = student.cg;
                final cityName = student.city;
                final studentName = student.studentName;
                return SizedBox(
                  child: Padding(
                    padding: const EdgeInsets.all(30.0),
                    child: SingleChildScrollView(
                      child: GestureDetector(
                        onDoubleTap: () {
                          edit(context, id!, studentName!, father, mother, cg, cityName!);
                        },
                        child: Column(
                          children: [
                            CustomReadOnlyField(hintText: id.toString()),
                            CustomReadOnlyField(hintText: studentName),
                            CustomReadOnlyField(hintText: father),
                            CustomReadOnlyField(hintText: mother),
                            CustomReadOnlyField(hintText: cg.toString()),
                            CustomReadOnlyField(hintText: cityName),
                          ],
                        ),
                      ),
                    ),
                  ),
                );
              }),
              scrollDirection: Axis.vertical,
            ),
          ),
        ),
      );
    } else {
      return const Center(child: CircularProgressIndicator());
    }
  },
),
英文:

I have a Future Builder in my flutter app and it displays --

  1. Error : if there's an error in json parsing
  2. Data : if everything goes smooth
  3. Loader : if its taking time

Everything works. the Future is calling a 'future' function thats doing a get request of some student data and the 'builder' is displaying it. I have an edit dialog box on the same page. I can edit the student information through the put request. The problem is that when I click on the form fields in the edit dialog box, I notice that get request is automatically happening approx 10 times. When I save the edits, a confirmation dialog box appears that data is updated. While this happens again get requests happens upto 10 times. And then it pops. So there are round about 20 useless requests happening on the server.
I think it happens because when I click the form fields the keyboard appears and the underlying displaying widget rebuilds, calling the api. When data is edited keyboards goes back into its place again widget rebuilds, calling the api. How can I resolve this issue ?

this is the code if it helps :

 child: FutureBuilder(
            future: APIs().getStudentDetails(),
            builder: (context, data) {
              if (data.hasError) {
                return Padding(
                    padding: const EdgeInsets.all(8),
                    child: Center(child: Text(&quot;${data.error}&quot;)));
              } else if (data.hasData) {
                var studentData = data.data as List&lt;StudentDetails&gt;;
                return Padding(
                  padding: const EdgeInsets.fromLTRB(0, 15, 0, 0),
                  child: SingleChildScrollView(
                    child: SizedBox(
                      height: MediaQuery.of(context).size.height * 0.9,
                      child: ListView.builder(
                        itemCount: studentData.length,
                        itemBuilder: ((context, index) {
                          final student = studentData[index];
                          final id = student.studentId;
                          final father = student.fatherName;
                          final mother = student.motherName;
                          final cg = student.cg;
                          final cityName = student.city;
                          final studentName = student.studentName;
                          return SizedBox(
                            child: Padding(
                              padding: const EdgeInsets.all(30.0),
                              child: SingleChildScrollView(
                                child: GestureDetector(
                                  onDoubleTap: () {
                                    edit(context, id!, studentName!, father,
                                        mother, cg, cityName!);
                                  },
                                  child: Column(children: [
                                    CustomReadOnlyField(
                                        hintText: id.toString()),
                                    CustomReadOnlyField(hintText: studentName),
                                    CustomReadOnlyField(hintText: father),
                                    CustomReadOnlyField(hintText: mother),
                                    CustomReadOnlyField(
                                        hintText: cg.toString()),
                                    CustomReadOnlyField(hintText: cityName),
                                  ]),
                                ),
                              ),
                            ),
                          );
                        }),
                        scrollDirection: Axis.vertical,
                      ),
                    ),
                  ),
                );
              } else {
                return const Center(child: CircularProgressIndicator());
              }
            },
          ),

答案1

得分: 1

我按照这个答案进行了操作,它起作用了。https://stackoverflow.com/questions/57793479/flutter-futurebuilder-gets-constantly-called
显然,我必须“延迟初始化我的 Future”和“在 initState 中初始化我的 Future”。

英文:

I followed this answer and it worke. https://stackoverflow.com/questions/57793479/flutter-futurebuilder-gets-constantly-called
Apparantly I had to 'Lazily initializing my Future' and 'Initializing my Future in initState:'

答案2

得分: 0

创建一个名为future的状态变量,如下所示:

late final future = APIs().getStudentDetails();

然后使用:

FutureBuilder(
   future: future ,

你可以参考修复常见的FutureBuilder和StreamBuilder问题

英文:

Create a state variable for future like

late final future = APIs().getStudentDetails();

and use

FutureBuilder(
   future: future ,

You can check Fixing a common FutureBuilder and StreamBuilder problem

答案3

得分: 0

class _YourWidgetState extends State with AutomaticKeepAliveClientMixin {
@override
bool get wantKeepAlive => true;
}

所以,通过将你的小部件扩展为AutomaticKeepAliveClientMixin,Listview内部的项目将不会被重新生成。

英文:
class _YourWidgetState extends State&lt;YourWidget&gt; with AutomaticKeepAliveClientMixin&lt;YourWidget&gt; {
 @override
  bool get wantKeepAlive =&gt; true;

So extend your Widget with AutomaticKeepAliveClientMixin so items inside Listview will not be reproduced

huangapple
  • 本文由 发表于 2022年10月22日 17:54:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/74162552.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定