在构建查询小部件期间调用setState()或markNeedsBuild()

时间:2020-10-20 16:43:10

标签: flutter

我对Graphql Flutter有问题。 我正在尝试显示通过graphql检索到的搜索列表。

但是扑扑告诉我:

不能将该小部件标记为需要构建,因为该框架已经在构建小部件。仅当其某个祖先当前正在构建窗口小部件时,才可以将其标记为需要在构建阶段中构建。允许使用此异常是因为该框架在子代之前构建父窗口小部件,这意味着将始终构建脏后代。否则,框架在此构建阶段可能不会访问此小部件。

我添加了一些Future Builder来避免此类问题,但不幸的是,它似乎不起作用

这是我的代码:

Column(
                            children: [
                              Row(
                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                crossAxisAlignment: CrossAxisAlignment.center,
                                children: <Widget>[
                                  Flexible(
                                    flex: 5,
                                    child: AnimatedContainer(
                                      duration: Duration(milliseconds: 500),
                                      padding: EdgeInsets.symmetric(horizontal: 25),
                                      height: 42.0,
                                      width: width,
                                      decoration: BoxDecoration(
                                        borderRadius:
                                        BorderRadius.circular(20.0),
                                        color: const Color(0xffffffff),
                                        boxShadow: [
                                          BoxShadow(
                                            color: const Color(0x29000000),
                                            offset: Offset(0, 0),
                                            blurRadius: 12,
                                          ),
                                        ],
                                      ),
                                      child: Form(
                                        child: Row(
                                          mainAxisAlignment: MainAxisAlignment.spaceAround,
                                          children: [
                                            Flexible(
                                              flex: 1,
                                              child: Container(
                                                width: 17.0,
                                                height: 17.0,
                                                decoration: BoxDecoration(
                                                  image: DecorationImage(
                                                    image: const AssetImage(
                                                        'assets/images/XDSearch.png'),
                                                    fit: BoxFit.cover,
                                                  ),
                                                ),
                                              ),
                                            ),
                                            Flexible(
                                              flex: 6,
                                              child: TextFormField(
                                                onChanged: (value){
                                                  setState(() {
                                                    textSearch = value;
                                                  });
                                                },
                                                keyboardType: TextInputType.emailAddress,
                                                decoration: const InputDecoration(
                                                    focusedBorder: InputBorder.none,
                                                    enabledBorder: InputBorder.none,
                                                    errorBorder: InputBorder.none,
                                                    disabledBorder: InputBorder.none,
                                                    border: InputBorder.none,
                                                    hintText: 'Recherche'
                                                ),
                                                style: TextStyle(
                                                  fontFamily: 'Roboto',
                                                  fontSize: 16,
                                                  color: const Color(0x8c000000),
                                                  fontWeight: FontWeight.w700,
                                                ),
                                                textAlign: TextAlign.left,
                                                focusNode: _focus,
                                              ),
                                            )
                                          ],
                                        ),
                                      ),
                                    ),
                                  ),
                                  clickOnBar == false ? Flexible(
                                    flex: 1,
                                    child: Column(
                                      mainAxisAlignment: MainAxisAlignment.center,
                                      crossAxisAlignment: CrossAxisAlignment.end,
                                      children: [
                                        Container(
                                          width: 30.0,
                                          height: 30.0,
                                          margin: EdgeInsets.fromLTRB(0, 0, 0, 0),
                                          decoration: BoxDecoration(
                                            borderRadius: BorderRadius.circular(15.0),
                                            image: DecorationImage(
                                              image: const AssetImage('assets/images/XDProfil.png'),
                                              fit: BoxFit.fill,
                                            ),
                                          ),
                                        )
                                      ],
                                    ),
                                  ) : Container()
                                ],
                              ),
                              textSearch != null && textSearch != 'undefined' && textSearch.isNotEmpty  ? FutureBuilder(
                                  builder: (context, projectSnap) {
                                    return Query(
                                      options: QueryOptions(
                                          documentNode: gql("""
                                            query getListSearch(\$text : String!){
                                              listSearchProPages(text: \$text) {
                                                categorie {
                                                  idCat
                                                  title
                                                }
                                                subCat {
                                                  idSubCat
                                                  title
                                                }
                                                pagePro {
                                                  idPagesPro
                                                  title
                                                }
                                              }
                                            }
                                          """
                                          ),
                                          variables: <String, dynamic>{
                                            "text": textSearch,
                                          },
                                          pollInterval: 10
                                      ),
                                      builder: (QueryResult result, {VoidCallback refetch, FetchMore fetchMore}){
                                        print(result);

                                        if (result.hasException) {
                                          return Text(result.exception.toString());
                                        }
                                        if (result.loading) {
                                          return Text('Loading');
                                        }

                                        var tmpObject = {
                                          "categorie": result.data['listSearchProPages'].first['categorie'],
                                          "subCat":  result.data['listSearchProPages'].first['subCat'],
                                          "pagePro":  result.data['listSearchProPages'].first['pagePro'],
                                        };

                                        return FutureBuilder(
                                            future: updateListSearch(tmpObject),
                                            builder: (context, projectSnap){
                                              if(tmpObject.length > 0) {
                                                ListView.builder(
                                                    itemCount: tmpObject.length,
                                                    itemBuilder: (context, index) {
                                                      print(tmpObject);
                                                      final repository = tmpObject[index];
                                                      print(repository["categorie"]
                                                          .first['title']);
                                                      return Text(
                                                          repository["categorie"]
                                                              .first['title']);
                                                    }
                                                );
                                              }else {
                                                return Container();
                                              }
                                              return Container();
                                            }
                                        );
                                      },
                                    );
                                  }
                              ) : Container()
                            ],
                          ),

您有解决方案吗?

1 个答案:

答案 0 :(得分:1)

请不要像现在那样在每次调用build方法时创建新的未来。

您需要一次创建将来的 (或者可能会更频繁地创建一次,但肯定不是在每个构建中都这样),然后在构建方法中使用 that 将来:

在状态类中创建一个将来类型的变量。

在initState方法中,通过将updateListSearch(tmpObject)的结果分配给变量来创建未来。

在构建方法中,将变量用作FutureBuilder中将来的参数。