Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.4k views
in Technique[技术] by (71.8m points)

dart - flutter: requests are spamed when the widget rebuild

So I am pretty new to flutter and I have this problem where the HTTP requests are spammed from previous screens when the widgets are rebuild by opening the keyboard.

For instance I have one screen called ActivityDetailsScreen in which I have a request that gets 1 activity. On that screen I also have a button to go to another page and there I can edit a textfield and every time I open or close the keyboard the widget reloads and the request from the previous page is executed.

Is there a way to avoid this?

EDIT:

I execute the request in the constructor of the screen

ActivityDetailsScreen({
    this.activityIndexString,
    this.idActivity,
    this.idUserProject,
    this.idProject,
    this.idUser,
    this.isOpenProject,
    this.deadLine,
    this.feedback,
  }) {
    ActivitiesService activitiesService = Get.find();
    this.activity = activitiesService.getActivity(this.idActivity);
  }

this is how I go to the next screen.

...
child: CupertinoButton(
                  child: Text(
                    isOpenProject
                        ? S.current.workOnProject
                        : S.current.viewProject,
                    textAlign: TextAlign.center,
                    style: TextStyle(
                      color: Colors.white,
                      fontFamily: FontNameDefault,
                      fontWeight: FontWeight.w600,
                      fontSize: 15.0,
                    ),
                  ),
                  onPressed: () {
                    Navigator.of(context).push(CupertinoPageRoute<void>(
                      builder: (BuildContext context) {
                        context
                            .bloc<AddImagesBloc>()
                            .add(LoadImagesEvent(idUserProject: idUserProject));
                        return AddImagesScreen(
                          idUserProject: idUserProject,
                          activityTitle: activityEntity.title,
                          isOpenProject: isOpenProject,
                          feedback: this.feedback,
                        );
                      },
                    ));
                  },
                  padding: EdgeInsets.all(8.0),
                ),
                ...

activities_service.dart file is where the HTTP request is called. this function is called in the constructor of the ActivityDetailsScreen constructor (shown in the first code snippet).

Future<ActivityEntity> getActivity(String id) async {
    QueryResult result = await this.client.query(
          QueryOptions(
            document: tgql(GQLQuery.activity),
            variables: {"id": id},
          ),
        );
    var data = result.data['activity'];
    if (useMockData)
      return mockActivities.firstWhere((element) => element.id == id);
    return ActivityEntity.fromJson(data);
  }
question from:https://stackoverflow.com/questions/65845936/flutter-requests-are-spamed-when-the-widget-rebuild

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You should probably be performing the HTTP call outside of ActivityDetailsScreen and just passing in the results via constructor args, and not performing any type of async work inside of the constructor itself.

I'm assuming you're using the Get package for state management (judging by your Get.find() call).

A GetxController would be the right place to make an HTTP call and storing the results for use wherever/whenever, completely outside of the lifecycle of display widgets such as ActivityDetailsScreen.

Widgets, especially StatelessWidgets, can be destroyed/recreated or rebuilt very often. The opening/closing of the software keyboard is a perfect example. It causes the constraints (available space to render) for widgets to change, therefore the widgets are rebuilt.


I'm not really clear on what's happening with the .bloc & .add in your code here, but it's probably not the right place to be doing that either. I'm guessing you're trying to navigate to a new page / route (the destination being AddImagesScreen).

                  onPressed: () {
                    Navigator.of(context).push(CupertinoPageRoute<void>(
                      builder: (BuildContext context) {
                        context
                            .bloc<AddImagesBloc>()
                            .add(LoadImagesEvent(idUserProject: idUserProject));
                        return AddImagesScreen(
                          idUserProject: idUserProject,
                          activityTitle: activityEntity.title,
                          isOpenProject: isOpenProject,
                          feedback: this.feedback,
                        );
                      },
                    ));
                  },

And you're seeing the ActivityDetailsScreen being rebuilt/HTTP call happening when you're opening/closing a keyboard on the AddImagesScreen?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...