preface

In the previous article we introduced the use of GetBuilder for simple state management. In this article we will continue to update the interface after completing network requests in state management. In this chapter, we will compare the differences between GetX and Provider, and learn about the state management of Flutter.

The status code

Here we still use Dio for network requests, the original request related code we directly copied, the source code can be downloaded here: GetX application code. Enter the state management code in VSCode’s edit screen by entering the getcontroller code template directive (with the GetX Snippets extension installed). Here we have two status properties. One is the network request status enumeration _loadingStatus, which indicates the network request status. The other is the Nuggets’ _personalProfile. In the constructor we pass the user ID to request personal information data. As you can see, the actual code is basically the same as the counter, updating the status object with the latest value, using the Update notification interface to refresh. The difference is that we have introduced a GetxController lifecycle function, onReady, to make network requests. OnReady is described in GetX as follows:

Called 1 frame after onInit(). It is the perfect place to enter navigation events, like snackbar, dialogs, or a new route, or async request. A frame call after onInit() is ideal for placing navigational entry events such as SnackBar, dialogs, new routes, or asynchronous requests.

The life cycle of GetxController will be covered in more detail in the next article, but now we know that GetX recommends making network requests at onReady.

enum LoadingStatus {
  loading,
  success,
  failed,
}

class PersonalController extends GetxController {
  static PersonalController get to => Get.find();
  final String userId;
  PersonalController({required this.userId});

  @override
  void onReady() {
    getPersonalProfile(userId);
    super.onReady();
  }

  PersonalEntity? _personalProfile;
  get personalProfile => _personalProfile;

  LoadingStatus _loadingStatus = LoadingStatus.loading;
  get loadingStatus => _loadingStatus;

  void getPersonalProfile(String userId) async {
    _loadingStatus = LoadingStatus.loading;
    _personalProfile = await JuejinService.getPersonalProfile(userId);
    if(_personalProfile ! =null) {
      _loadingStatus = LoadingStatus.success;
    } else{ _loadingStatus = LoadingStatus.failed; } update(); }}Copy the code

Interface code

The interface code is subsidized and we will only compare the difference with the Provider.

  • Outermost code: The main reason for this is that the Provider needs to share widgets with lower-level components. It doesn’t look too different.
// GetX outermost layer
class PersonalHomePageWrapper extends StatelessWidget {
  const PersonalHomePageWrapper({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetBuilder<PersonalController>(
      init: PersonalController(userId: '70787819648695'), builder: (controller) => _PersonalHomePage(), ); }}/ / the Provider's outermost
class PersonalHomePageWrapper extends StatelessWidget {
  const PersonalHomePageWrapper({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    returnFutureProvider<PersonalEntity? >( create: (context) => JuejinService.getPersonalProfile('70787819648695'),
      initialData: null, child: _PersonalHomePage(), ); }}Copy the code
  • Actual page code: The two parts of the code look almost the same, as they both grab the state object and build the page. To be more semantically accurate, we have added a network load attribute to identify the request. Here it looks like if you go fromProviderSwitch to theGetXAnd in the use ofGetBuilderWith this simple state management approach, code changes should be minimal. In fact, the biggest difference between the two parts of the code isGetXNo need to usecontextTo get the state object.
/ / GetX code
@override
  Widget build(BuildContext context) {
    if (PersonalController.to.loadingStatus == LoadingStatus.loading) {
      return Center(
        child: Text('Loading... ')); }if (PersonalController.to.loadingStatus == LoadingStatus.failed) {
      return Center(
        child: Text('Request failed')); } PersonalEntity personalProfile = PersonalController.to.personalProfile;return Stack(
      children: [
        CustomScrollView(
          slivers: [
            _getBannerWithAvatar(context, personalProfile),
            _getPersonalProfile(personalProfile),
            _getPersonalStatistic(personalProfile),
          ],
        ),
     / /...
}

/ / the Provider code
class _PersonalHomePage extends StatelessWidget {
  const _PersonalHomePage({Key? key}) : super(key: key);

  @overrideWidget build(BuildContext context) { PersonalEntity? personalProfile = context.watch<PersonalEntity? > ();if (personalProfile == null) {
      return Center(
        child: Text('Loading... ')); }return Stack(
      children: [
        CustomScrollView(
          slivers: [
            _getBannerWithAvatar(context, personalProfile),
            _getPersonalProfile(personalProfile),
            _getPersonalStatistic(personalProfile),
          ],
        ),
  / /...
}
Copy the code

So what’s GetX’s advantage? Let’s make a copy of the code for our personal home page, but we won’t use it anymoreGetBuilderThen add a button from your home page and click the back path to go to that page (see the image below, we changed the background image to distinguish it).At this point, the page has nothing to do with the previous page, but it can still be usedPersonalController.to.personalProfileAccess to personal information data. Part of the code looks like this:

class PersonalHomePageCopy extends StatelessWidget {
  const PersonalHomePageCopy({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    PersonalEntity personalProfile = PersonalController.to.personalProfile;
    return Stack(
      children: [
        CustomScrollView(
          slivers: [
            _getBannerWithAvatar(context, personalProfile),
            _getPersonalProfile(personalProfile),
            _getPersonalStatistic(personalProfile),
          ],
        ),
  / /...
}
Copy the code

This makes the reuse of state data much simpler. Once the state object is initialized, it can be used by any component — there is no need for any association between components, such as a common parent component.

conclusion

This article describes the asynchronous request refresh interface in GetX state management, and the use of Provider for state management code. You can see that GetX has the following features:

  • Asynchronous requests are no different from normal state management and are fairly simple;
  • fromProviderMigration toGetXNot much code to modify;
  • GetXThe state sharing method is simpler, without any association between components, as long as the state object is initialized, it can be accessed from any component. This is theGetXThe real advantage.

I am dao Code Farmer with the same name as my wechat official account. This is a column about the introduction and practice of Flutter, providing systematic learning articles about Flutter. See the corresponding source code here: The source code of Flutter Introduction and Practical column. If you have any questions, please add me to the wechat account: island-coder.

👍🏻 : feel the harvest please point a praise to encourage!

🌟 : Collect articles, easy to look back!

💬 : Comment exchange, mutual progress!