Graphql-flutter: When i navigate to a new screen, all queries that in ancestry routers will refetch, how can i stop it

Created on 6 Dec 2019  路  9Comments  路  Source: zino-app/graphql-flutter

flutter help wanted investigate needs more info

Most helpful comment

This is not a graphql-flutter bug per-se, as it is a nasty issue with the flutter framework and its handling of route navigation.

Until the bug is fixed on the framework, you may want to avoid the Query widget, and use the graphql client directly in the initState of your widget.

Here's the issue
https://github.com/flutter/flutter/issues/11655

All 9 comments

We would appreciate it if you could provide us with more info about this issue/pr!

This is an issue i'm facing as well. After pushing a new route to the stack using Navigator, the setState method is called on the parent/previous widget in the stack, as intended. This setState call does however also rebuild the Query widgets in the parent, causing them execute the GrahpQL query again, even though the Query widgets have not changed. If i have understood correctly, these queries should not be executed again since they have not changed?

Have you tried the latest beta? And there is a reason we ask for the flutter version and package version being used, to avoid someone reasking the question. If you are already using the latest beta version, please provide a sample code.

Sample code provided below along with flutter doctor output. This is tested on the latest version of the package (2.1.0). As mentioned above, pushing and popping a new page causes the Query widget to refetch the data from the server. This does not happen when calling setState on the widget containing the Query widget directly. I'm not sure if this can be seen from the app directly, I found out by looking at output from the GraphQL server. I have also tested using the latest beta (2.1.1-beta.4), but using this version the data is refetched from the server both when calling setState and using the navigator.

import 'package:flutter/material.dart';
import 'package:graphql_flutter/graphql_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    final HttpLink httpLink = HttpLink(uri: 'http://10.0.2.2:8000/graphql/');
    final AuthLink authLink = AuthLink(getToken: ()  => '');
    final Link link = authLink.concat(httpLink);

    ValueNotifier<GraphQLClient> client = ValueNotifier(
      GraphQLClient(
        cache: InMemoryCache(),
        link: link,
      ),
    );

    return GraphQLProvider(
      client: client,
      child: MaterialApp(
        title: 'Flutter Demo',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: MyHomePage(),
      ),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Column(
        children: <Widget>[
          RaisedButton(
            child: Text("setState"),
            onPressed: () => setState(() {}),
          ),
          RaisedButton(
            child: Text("Navigate"),
            onPressed: () => Navigator.of(context).push(MaterialPageRoute(builder: (context) => NewPage(), maintainState: false)),
          ),
          Query(
            options: QueryOptions(
                document: query
            ),
            builder: (QueryResult result, { VoidCallback refetch, FetchMore fetchMore }){
              if(result.errors != null)
                print(result.errors);

              if(result.data != null){
                print(result.data);
              }

              return Container();
            },
          ),
        ],
      ),
    );
  }

  String query = """
  query{
    shop{
      name
    }
  }
  """;
}

class NewPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
    );
  }
}

Flutter doctor:

Doctor summary (to see all details, run flutter doctor -v):
[鈭歖 Flutter (Channel stable, v1.9.1+hotfix.6, on Microsoft Windows [Version 10.0.18362.476], locale nb-NO)
[鈭歖 Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[鈭歖 Android Studio (version 3.5)
[!] VS Code (version 1.39.2)
    X Flutter extension not installed; install from
      https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter
[鈭歖 Connected device (1 available)

! Doctor found issues in 1 category.

This is not a graphql-flutter bug per-se, as it is a nasty issue with the flutter framework and its handling of route navigation.

Until the bug is fixed on the framework, you may want to avoid the Query widget, and use the graphql client directly in the initState of your widget.

Here's the issue
https://github.com/flutter/flutter/issues/11655

@hchoff you can set proxy for all of the connections as below, then you can catch all queries of application.

class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext context) {
return super.createHttpClient(context)
..findProxy = (uri) {
return "PROXY 192.168.1.157:8001;";
}
..badCertificateCallback =
(X509Certificate cert, String host, int port) => true;
}
}

void main() {
HttpOverrides.global = new MyHttpOverrides();
runApp(child: MyApp());
}

This issue doesn't seem like it was resolved but it was closed.

This issue doesn't seem like it was resolved but it was closed.
yes锛宐ut why锛宼his state keep two years

I have a temporary solution to the problem of rebuilding锛宎nd I hope it will work for you.

https://github.com/jackleemeta/flutter_should_build

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dopecoder picture dopecoder  路  4Comments

micimize picture micimize  路  4Comments

jomag picture jomag  路  3Comments

campanagerald picture campanagerald  路  3Comments

vanelizarov picture vanelizarov  路  3Comments