ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Flutter_18. App State_Provider(feat. Riverpod)
    > Frontend/Flutter 2023. 5. 21. 18:04

     

     

     

    0. 학습내용

       - State 

       - Provider

       -Riverpods

     

    1. State의 두 종류, App State 와 Widget State

    •     App State: Flutter App 전반에서 사용되는 data 로, 여러  Widget 에서 공통적으로 사용되는 것을 의미. 
    •    Widget State: Ephemeral State | Local State라고도 불리며, 한 Widget 에서만 사용되는 것을 의미. 

     

    2. Provider 란 ? 

    • concept of "InheritedWidget" and "ChangeNotifier" to manage application state

    Provider를 사용하여, 전역적으로 State를 관리

     

    • Provider를 통해서 전달해줘도 되지만, 이번 포스트는 Rivepods를 사용할 예정

     

    3. Riverpods

     

    •    Riverpod: state management package to solve Provider’s flaws
    • 1) 설치 
     $ flutter pub add provider

     

    • 2) Main.dart 변경
    import 'package:flutter/material.dart';
    
    import 'package:flutter_riverpod/flutter_riverpod.dart';
    
    
    ... 생략
    
    void main() {
      runApp(const ProviderScope(child: App()));
    }
    
    
    ... 생략

    -  사용하기 위해서는 App을 ProviderScope 로 감싸줘야한다.

     

    • 3)  Provider 정의 
    import 'package:flutter_riverpod/flutter_riverpod.dart';
    
    .. 생략
    
    final filtersProvider =
        StateNotifierProvider<FiltersNotifier, Map<Filter, bool>>(
      (ref) => FiltersNotifier(),
    );
    
    
    .. 생략

    -  import 한 Provider Class를 사용하여, state provider를 생성.

    -  어느 widget 에서 filterProvider를 호출하면, 동일한 dart file에 있는 FiltersNotifier 호출

     

     

    class FiltersNotifier extends StateNotifier<Map<Filter, bool>> {
      FiltersNotifier()
          : super({
              Filter.glutenFree: false,
              Filter.lactoseFree: false,
              Filter.vegetarian: false,
              Filter.vegan: false,
            });
    
      void setFilter(Filter filter, bool isActive) {
        state = {...state, filter: isActive};
      }
      void setFilters(Map<Filter, bool> chosenFilters){
        state = chosenFilters;
      }
    
    }

     

     

    4) Consume Provider (in ConsumerWidget)

     

    - Provider를 사용하기 위해서는 ,  사용하는 class가 ConsumerStatefulWidget을 상속하고, _TabScreenState도 ConsumerState를 상속

    ...생략
    
    class FiltersScreen extends ConsumerStatefulWidget {
      const FiltersScreen({Key? key}) : super(key: key);
    
      @override
      ConsumerState<FiltersScreen> createState() => _FiltersScreenState();
    }
    
    class _FiltersScreenState extends ConsumerState<FiltersScreen> {
    
    ...생략

     

    -   해당 Widget에서, ref를 사용하면, RiverPod의 다양한 option을 사용할 수 있다. 

    -   ref.read() 를 사용하면, filtersProvider에 있는 값들을 사용할 수 있다. 

    -   ref.watch()를 사용하면, .read()와 같이 Provider를 사용할 수 있지만, read와의 차이점으로는, watch는 provider내의 state값이 변경될 때, widget을 rebuild를 해준다.

     

    1) 방식 1

    final activeFilters = ref.read(filtersProvider);
    _glutenFreeFilterSet = activeFilters[Filter.glutenFree]!;
    _lactoseFreeFilterSet = activeFilters[Filter.lactoseFree]!;
    _vegeterianFreeFilterSet = activeFilters[Filter.vegetarian]!;
    _veganFreeFilterSet = activeFilters[Filter.vegan]!;
    final activeFilters = ref.watch(filtersProvider);

    2) 방식 2

    ref.read(filtersProvider.notifier).setFilters({
      Filter.glutenFree: _glutenFreeFilterSet,
      Filter.lactoseFree: _lactoseFreeFilterSet,
      Filter.vegetarian: _vegeterianFreeFilterSet,
      Filter.vegan: _veganFreeFilterSet
    });

    -   .notifier를 사용하는 이유는, 값을 수정하고 싶을때에만 .notifier로 추가 접근한다. 

     

     

     

     

     

     

     

    댓글

Designed by Tistory.