【Flutter】실천! state_notifier + freezed로 Google Books API를 두드려보자 【초보자용】

18567 단어 DartFlutter

2021/7/3 추가



공급자의 상위 버전 라이브러리 인 Riverpod에서 다시 작성된 샘플도 만들었습니다!
Null 안전에서도 (일단) 움직이도록 수정하고 있습니다.
StateNotifier의 선언도 파일내에 쓸 뿐이라는 간단 사양이 되는 등, 여러가지 메리트가 있기 때문에, 향후는 이쪽으로 쓰는 편이 좋을 것 같네요!

htps : // 기주 b. 이 m / a lp는 2048 / ri ょ r po d_

안녕하세요, Flutter 사람입니다

개요



여기 최근 Flutter에서 뜨거운 패키지로 다음 패키지가 있습니다.

  • freezed
  • 이른바 data 클래스적인 것을 사쿠로 만들 수 있는 패키지
  • json 주위의 코드를 자동 생성해 주므로 API의 접시에도 사용할 수 있습니다


  • state_notifier
  • 상태 관리를 제공하는 패키지
  • 참조하기 쉬운 ViewModel적인 것을 쉽게 만들 수 있습니다


  • 이것을 사용하여 실제로 Google Books API를 두드려 정보를 표시하는 앱을 만들었습니다.
    (항에는 카운터 앱의 샘플은 많이 있는데, 어째서 API 부르는 것 같은 샘플은 없어··라고 생각하면서 만들었습니다.

    전제



    각 패키지에 대한 자세한 설명은 생략했지만 다음 기사가 도움이됩니다.
  • Flutter freezed 패키지 좋은 느낌일지도
  • state_notifier와 freezed를 사용하여 Flutter 카운터 앱을 만듭니다.
  • Flutter의 StateNotifier 패턴으로 카운트 업 앱을 만들어 보았습니다.
  • Flutter state_notifier 좋은 느낌이므로 사용하는 것이 좋습니다.

  • 샘플



    htps : // 기주 b. 이 m / a lp는 2048 / S 갓 따뜻한 r st

    ↓ iOS의 표시 예



    해설



    패키지 설치



    어쨌든 패키지 종류의 설치입니다.
    여기서 flutter_state_notifier공급자도 함께 설치하면 state_notifier를 더 편안하게 사용할 수 있습니다.
    API 호출을 수행하기 위해 http도 넣습니다.

    pubspec.yaml
    dependencies:
      flutter:
        sdk: flutter
      cupertino_icons: ^0.1.3
    
      state_notifier: ^0.5.0
      flutter_state_notifier: ^0.4.2
      freezed_annotation: ^0.11.0
      provider: ^4.3.1
      json_annotation: ^3.0.1
      http: ^0.12.2
      url_launcher: ^5.5.0
    
    dev_dependencies:
      flutter_test:
        sdk: flutter
      json_serializable: ^3.3.0
      build_runner: ^1.10.0
      freezed: ^0.11.4
    

    모델



    Response



    freezed로 만들어 갑니다.
    만약 끝나면 flutter pub run build_runner build 를 두드려 build합시다.

    GoogleBooksResponse.dart
    import 'package:flutter/foundation.dart';
    import 'package:freezed_annotation/freezed_annotation.dart';
    import 'package:state_notifier_test/model/GoogleBookResponse.dart';
    part 'GoogleBooksResponse.freezed.dart';
    part 'GoogleBooksResponse.g.dart';
    
    @freezed
    abstract class GoogleBooksResponse with _$GoogleBooksResponse {
      const factory GoogleBooksResponse({
        String kind,
        int totalItems,
        List<GoogleBookResponse> items
      }) = _GoogleBooksResponse;
    
      factory GoogleBooksResponse.fromJson(Map<String, dynamic> json) => _$GoogleBooksResponseFromJson(json);
    }
    

    API



    http로 호출하고 방금 freeezed로 만든 Response 클래스에서 decode합니다.

    GoogleBooksAPIService.dart
    import 'dart:convert' as convert;
    import 'package:http/http.dart' as http;
    import 'package:state_notifier_test/model/GoogleBooksResponse.dart';
    
    Future<GoogleBooksResponse> getBooks(String keyword) async {
    
      var url = 'https://www.googleapis.com/books/v1/volumes?q=$keyword';
      print(url);
    
      final response = await http.get(url);
      if (response.statusCode == 200) {
        return GoogleBooksResponse.fromJson(convert.jsonDecode(response.body));
      } else {
        throw Exception('Failed to connect to webservice');
      }
    }
    

    ViewModel



    State



    StateNotifier가 관리하는 State입니다.
    이쪽도 만들고 끝나면 build합시다.

    실제로 View측에서 사용하는 응답 외에 상태를 통지하는 Enum을 정의하고 있습니다.

    MainViewModelData.dart
    import 'package:freezed_annotation/freezed_annotation.dart';
    import 'package:state_notifier_test/model/GoogleBooksResponse.dart';
    
    part 'MainViewModelData.freezed.dart';
    
    enum MainViewModelState { normal, loading, error }
    
    @freezed
    abstract class MainViewModelData with _$MainViewModelData {
      const factory MainViewModelData({
        GoogleBooksResponse response,
        MainViewModelState viewModelState
      }) = _MainViewModelData;
    }
    

    StateNotifier



    StateNotifier의 구현입니다.
    간단하고 이해하기 쉽습니다.

    MainViewModel.dart
    import 'package:state_notifier/state_notifier.dart';
    import 'package:state_notifier_test/model/GoogleBooksAPIService.dart';
    import 'package:state_notifier_test/view/MainViewModelData.dart';
    
    class MainViewModel extends StateNotifier<MainViewModelData> {
      MainViewModel(): super(MainViewModelData());
    
      void fetch(String keyword) {
        state = state.copyWith(viewModelState: MainViewModelState.loading);
        getBooks(keyword)
            .then((res) {
              state = state.copyWith(response: res, viewModelState: MainViewModelState.normal);
            }).catchError((_) {
              state = state.copyWith(response: null, viewModelState: MainViewModelState.error);
            });
      }
    }
    

    보기



    StateNotifier 생성



    ViewModel을 사용하는 Widget의 친측의 어느 곳에서나 StateNotifier를 생성합니다.
    여러 Widget에서 참조하고 싶다면 가능한 한 상층 측에서 정의해 봅시다.

    main.dart
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return MaterialApp(
          title: 'Google Book State Notifier Sample',
          theme: ThemeData(
            primarySwatch: Colors.blue,
            visualDensity: VisualDensity.adaptivePlatformDensity,
          ),
          home: StateNotifierProvider<MainViewModel, MainViewModelData>(
            create: (_) => MainViewModel(),
            child: MyHomePage(title: 'Google Book State Notifier Sample'),
          ),
        );
      }
    }
    

    StateNotifier의 State 읽기


    context.select<Data, T>에서 데이터를 읽습니다.select 를 사용하면 데이터에 변화가 있을 때 자동으로 rebuild 합니다.

    main.dart
    final response = context.select<MainViewModelData, GoogleBooksResponse>((data) => data.response);
    final state = context.select<MainViewModelData, MainViewModelState>((data) => data.viewModelState);
    final List<GoogleBookResponse> bookList = response != null ? response.items : [];
    

    그리고는 읽은 데이터를 참고로 View를 만들어 가는 것뿐입니다!

    결론



    Flutter는 BLoC 패턴 등 아키텍처 주위가 약간 어렵다는 인상이 있었습니다만, state_notifier를 사용하면 MVVM 패턴을 깨끗이 쓸 수 있게 되어, 개인적으로는 매우 기쁜 진화를 이루고 있습니다.
    앞으로는 state_notifier가 일반적으로 될 것입니까?

    참고 자료


  • Flutter freezed 패키지 좋은 느낌일지도
  • state_notifier와 freezed를 사용하여 Flutter 카운터 앱을 만듭니다.
  • Flutter의 StateNotifier 패턴으로 카운트 업 앱을 만들어 보았습니다.
  • Flutter state_notifier 좋은 느낌이므로 사용하는 것이 좋습니다.
  • Flutter 전부 나 Advent Calendar 2019
  • 좋은 웹페이지 즐겨찾기